mirror of
https://github.com/creating2morrow/neveko.git
synced 2025-01-20 17:54:34 +00:00
organize lmdb keys and order bug fix
This commit is contained in:
parent
4bff85e7f6
commit
c47ca7494e
13 changed files with 332 additions and 88 deletions
|
@ -32,7 +32,7 @@ use std::collections::BTreeMap;
|
||||||
/// Create authorization data to sign and expiration
|
/// Create authorization data to sign and expiration
|
||||||
pub fn create(address: &String) -> Authorization {
|
pub fn create(address: &String) -> Authorization {
|
||||||
info!("creating auth");
|
info!("creating auth");
|
||||||
let aid: String = format!("auth{}", utils::generate_rnd());
|
let aid: String = format!("{}{}", crate::AUTH_DB_KEY, utils::generate_rnd());
|
||||||
let rnd: String = utils::generate_rnd();
|
let rnd: String = utils::generate_rnd();
|
||||||
let created: i64 = chrono::offset::Utc::now().timestamp();
|
let created: i64 = chrono::offset::Utc::now().timestamp();
|
||||||
let token: String = create_token(String::from(address), created);
|
let token: String = create_token(String::from(address), created);
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl Prune {
|
||||||
|
|
||||||
/// Create a new contact
|
/// Create a new contact
|
||||||
pub async fn create(c: &Json<Contact>) -> Contact {
|
pub async fn create(c: &Json<Contact>) -> Contact {
|
||||||
let f_cid: String = format!("c{}", utils::generate_rnd());
|
let f_cid: String = format!("{}{}", crate::CONTACT_DB_KEY, utils::generate_rnd());
|
||||||
info!("creating contact: {}", f_cid);
|
info!("creating contact: {}", f_cid);
|
||||||
let new_contact = Contact {
|
let new_contact = Contact {
|
||||||
cid: String::from(&f_cid),
|
cid: String::from(&f_cid),
|
||||||
|
@ -57,8 +57,8 @@ pub async fn create(c: &Json<Contact>) -> Contact {
|
||||||
let k = &new_contact.cid;
|
let k = &new_contact.cid;
|
||||||
db::Interface::write(&s.env, &s.handle, k, &Contact::to_db(&new_contact));
|
db::Interface::write(&s.env, &s.handle, k, &Contact::to_db(&new_contact));
|
||||||
// in order to retrieve all contact, write keys to with cl
|
// in order to retrieve all contact, write keys to with cl
|
||||||
let list_key = format!("cl");
|
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating contact index");
|
debug!("creating contact index");
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ pub fn find(cid: &String) -> Contact {
|
||||||
/// All contact lookup
|
/// All contact lookup
|
||||||
pub fn find_all() -> Vec<Contact> {
|
pub fn find_all() -> Vec<Contact> {
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
let list_key = format!("cl");
|
let list_key = crate::CONTACT_LIST_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
error!("contact index not found");
|
error!("contact index not found");
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rocket::serde::json::Json;
|
||||||
|
|
||||||
/// Create a new dispute
|
/// Create a new dispute
|
||||||
pub fn create(d: Json<Dispute>) -> Dispute {
|
pub fn create(d: Json<Dispute>) -> Dispute {
|
||||||
let f_did: String = format!("dispute{}", utils::generate_rnd());
|
let f_did: String = format!("{}{}", crate::DISPUTE_DB_KEY, utils::generate_rnd());
|
||||||
info!("create dispute: {}", &f_did);
|
info!("create dispute: {}", &f_did);
|
||||||
let new_dispute = Dispute {
|
let new_dispute = Dispute {
|
||||||
did: String::from(&f_did),
|
did: String::from(&f_did),
|
||||||
|
|
|
@ -15,6 +15,8 @@ use std::{
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO(c2m): remove this module and use monero public keys for text encryption
|
||||||
|
|
||||||
/// Searches for key, returns empty string if none exists
|
/// Searches for key, returns empty string if none exists
|
||||||
///
|
///
|
||||||
/// TODO(c2m): add more cli options
|
/// TODO(c2m): add more cli options
|
||||||
|
|
|
@ -1,24 +1,43 @@
|
||||||
pub mod args; // command line arguments
|
pub mod args; // command line arguments
|
||||||
pub mod auth; // internal auth repo/service layer
|
pub mod auth; // internal auth repo/service layer
|
||||||
pub mod contact; // contact repo/service layer
|
pub mod contact; // contact repo/service layer
|
||||||
pub mod dispute; // Dispute repo/service layer
|
pub mod dispute; // dispute repo/service layer
|
||||||
pub mod db; // lmdb interface
|
pub mod db; // lmdb interface
|
||||||
pub mod gpg; // gpgme interface
|
pub mod gpg; // gpgme interface
|
||||||
pub mod i2p; // i2p repo/service layer
|
pub mod i2p; // i2p repo/service layer
|
||||||
pub mod message; // message repo/service layer
|
pub mod message; // message repo/service layer
|
||||||
pub mod models; // db structs
|
pub mod models; // db structs
|
||||||
pub mod monero; // monero-wallet-rpc interface
|
pub mod monero; // monero-wallet-rpc interface
|
||||||
pub mod order; // Order repo/service layer
|
pub mod order; // order repo/service layer
|
||||||
pub mod product; // Product repo/service layer
|
pub mod product; // product repo/service layer
|
||||||
pub mod proof; // external auth/payment proof module
|
pub mod proof; // external auth/payment proof module
|
||||||
pub mod reqres; // http request/responses
|
pub mod reqres; // http request/responses
|
||||||
pub mod user; // misc.
|
pub mod user; // user repo/service layer
|
||||||
pub mod utils; // user rep/service layer
|
pub mod utils; // misc.
|
||||||
|
|
||||||
pub const APP_NAME: &str = "neveko";
|
pub const APP_NAME: &str = "neveko";
|
||||||
pub const NEVEKO_JWP_SECRET_KEY: &str = "NEVEKO_JWP_SECRET_KEY";
|
pub const NEVEKO_JWP_SECRET_KEY: &str = "NEVEKO_JWP_SECRET_KEY";
|
||||||
pub const NEVEKO_JWT_SECRET_KEY: &str = "NEVEKO_JWT_SECRET_KEY";
|
pub const NEVEKO_JWT_SECRET_KEY: &str = "NEVEKO_JWT_SECRET_KEY";
|
||||||
|
|
||||||
|
// LMDB Keys
|
||||||
|
pub const AUTH_DB_KEY: &str = "a";
|
||||||
|
pub const CONTACT_DB_KEY: &str = "c";
|
||||||
|
pub const DISPUTE_DB_KEY: &str = "d";
|
||||||
|
pub const MESSAGE_DB_KEY: &str = "m";
|
||||||
|
pub const ORDER_DB_KEY: &str = "o";
|
||||||
|
pub const PRODUCT_DB_KEY: &str = "p";
|
||||||
|
pub const USER_DB_KEY: &str = "u";
|
||||||
|
pub const CONTACT_LIST_DB_KEY: &str = "cl";
|
||||||
|
pub const MESSAGE_LIST_DB_KEY: &str = "ml";
|
||||||
|
pub const ORDER_LIST_DB_KEY: &str = "ol";
|
||||||
|
pub const PRODUCT_LIST_DB_KEY: &str = "pl";
|
||||||
|
pub const RX_MESSAGE_DB_KEY: &str = "rx";
|
||||||
|
pub const FTS_DB_KEY: &str = "fts";
|
||||||
|
pub const CUSTOMER_ORDER_LIST_DB_KEY: &str = "olc";
|
||||||
|
pub const MSIG_MESSAGE_DB_KEY: &str = "msig";
|
||||||
|
pub const FTS_JWP_DB_KEY: &str = "fts-jwp";
|
||||||
|
// End LMDB Keys
|
||||||
|
|
||||||
/// Environment variable for injecting wallet password
|
/// Environment variable for injecting wallet password
|
||||||
pub const MONERO_WALLET_PASSWORD: &str = "MONERO_WALLET_PASSWORD";
|
pub const MONERO_WALLET_PASSWORD: &str = "MONERO_WALLET_PASSWORD";
|
||||||
/// Environment variable for I2P proxy host
|
/// Environment variable for I2P proxy host
|
||||||
|
|
|
@ -51,9 +51,9 @@ impl Default for MultisigMessageData {
|
||||||
/// Create a new message
|
/// Create a new message
|
||||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||||
let rnd = utils::generate_rnd();
|
let rnd = utils::generate_rnd();
|
||||||
let mut f_mid: String = format!("m{}", &rnd);
|
let mut f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, &rnd);
|
||||||
if m_type == MessageType::Multisig {
|
if m_type == MessageType::Multisig {
|
||||||
f_mid = format!("msig{}", &rnd);
|
f_mid = format!("{}{}", crate::MSIG_MESSAGE_DB_KEY, &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();
|
||||||
|
@ -73,8 +73,8 @@ pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Messa
|
||||||
let k = &new_message.mid;
|
let k = &new_message.mid;
|
||||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||||
// in order to retrieve all message, write keys to with ml
|
// in order to retrieve all message, write keys to with ml
|
||||||
let list_key = format!("ml");
|
let list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating message index");
|
debug!("creating message index");
|
||||||
}
|
}
|
||||||
|
@ -99,10 +99,10 @@ pub async fn rx(m: Json<Message>) {
|
||||||
if !is_in_contact_list {
|
if !is_in_contact_list {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let f_mid: String = format!("m{}", utils::generate_rnd());
|
let f_mid: String = format!("{}{}", crate::MESSAGE_DB_KEY, utils::generate_rnd());
|
||||||
let new_message = Message {
|
let new_message = Message {
|
||||||
mid: String::from(&f_mid),
|
mid: String::from(&f_mid),
|
||||||
uid: String::from("rx"),
|
uid: String::from(crate::RX_MESSAGE_DB_KEY),
|
||||||
from: String::from(&m.from),
|
from: String::from(&m.from),
|
||||||
body: m.body.iter().cloned().collect(),
|
body: m.body.iter().cloned().collect(),
|
||||||
created: chrono::offset::Utc::now().timestamp(),
|
created: chrono::offset::Utc::now().timestamp(),
|
||||||
|
@ -113,8 +113,8 @@ pub async fn rx(m: Json<Message>) {
|
||||||
let k = &new_message.mid;
|
let k = &new_message.mid;
|
||||||
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
db::Interface::write(&s.env, &s.handle, k, &Message::to_db(&new_message));
|
||||||
// in order to retrieve all message, write keys to with rx
|
// in order to retrieve all message, write keys to with rx
|
||||||
let list_key = format!("rx");
|
let list_key = crate::RX_MESSAGE_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating message index");
|
debug!("creating message index");
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ pub async fn rx_multisig(m: Json<Message>) {
|
||||||
let f_mid: String = format!("msig{}", utils::generate_rnd());
|
let f_mid: String = format!("msig{}", utils::generate_rnd());
|
||||||
let new_message = Message {
|
let new_message = Message {
|
||||||
mid: String::from(&f_mid),
|
mid: String::from(&f_mid),
|
||||||
uid: String::from("rx"),
|
uid: String::from(crate::RX_MESSAGE_DB_KEY),
|
||||||
from: String::from(&m.from),
|
from: String::from(&m.from),
|
||||||
body: m.body.iter().cloned().collect(),
|
body: m.body.iter().cloned().collect(),
|
||||||
created: chrono::offset::Utc::now().timestamp(),
|
created: chrono::offset::Utc::now().timestamp(),
|
||||||
|
@ -226,7 +226,7 @@ pub fn find(mid: &String) -> Message {
|
||||||
/// Message lookup
|
/// Message lookup
|
||||||
pub fn find_all() -> Vec<Message> {
|
pub fn find_all() -> Vec<Message> {
|
||||||
let i_s = db::Interface::open();
|
let i_s = db::Interface::open();
|
||||||
let i_list_key = format!("ml");
|
let i_list_key = crate::MESSAGE_LIST_DB_KEY;
|
||||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
if i_r == utils::empty_string() {
|
if i_r == utils::empty_string() {
|
||||||
error!("message index not found");
|
error!("message index not found");
|
||||||
|
@ -240,7 +240,7 @@ pub fn find_all() -> Vec<Message> {
|
||||||
messages.push(message);
|
messages.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let o_list_key = format!("rx");
|
let o_list_key = crate::RX_MESSAGE_DB_KEY;
|
||||||
let o_s = db::Interface::open();
|
let o_s = db::Interface::open();
|
||||||
let o_r = db::Interface::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
let o_r = db::Interface::read(&o_s.env, &o_s.handle, &String::from(o_list_key));
|
||||||
if o_r == utils::empty_string() {
|
if o_r == utils::empty_string() {
|
||||||
|
@ -350,8 +350,8 @@ async fn send_to_retry(mid: String) {
|
||||||
info!("sending {} to fts", &mid);
|
info!("sending {} to fts", &mid);
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
// in order to retrieve FTS (failed-to-send), write keys to db with fts
|
// in order to retrieve FTS (failed-to-send), write keys to db with fts
|
||||||
let list_key = format!("fts");
|
let list_key = crate::FTS_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating fts message index");
|
debug!("creating fts message index");
|
||||||
}
|
}
|
||||||
|
@ -366,8 +366,7 @@ async fn send_to_retry(mid: String) {
|
||||||
);
|
);
|
||||||
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);
|
||||||
// restart fts if not empty
|
// restart fts if not empty
|
||||||
let list_key = format!("fts");
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
|
||||||
let v_mid = r.split(",");
|
let v_mid = r.split(",");
|
||||||
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
let v: Vec<String> = v_mid.map(|s| String::from(s)).collect();
|
||||||
debug!("fts contents: {:#?}", v);
|
debug!("fts contents: {:#?}", v);
|
||||||
|
@ -383,8 +382,8 @@ fn remove_from_fts(mid: String) {
|
||||||
info!("removing id {} from fts", &mid);
|
info!("removing id {} from fts", &mid);
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
// in order to retrieve FTS (failed-to-send), write keys to with fts
|
// in order to retrieve FTS (failed-to-send), write keys to with fts
|
||||||
let list_key = format!("fts");
|
let list_key = crate::FTS_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("fts is empty");
|
debug!("fts is empty");
|
||||||
}
|
}
|
||||||
|
@ -417,7 +416,7 @@ pub async fn retry_fts() {
|
||||||
debug!("running retry failed-to-send thread");
|
debug!("running retry failed-to-send thread");
|
||||||
tick.recv().unwrap();
|
tick.recv().unwrap();
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
let list_key = format!("fts");
|
let list_key = crate::FTS_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
info!("fts message index not found");
|
info!("fts message index not found");
|
||||||
|
@ -430,7 +429,7 @@ pub async fn retry_fts() {
|
||||||
if cleared {
|
if cleared {
|
||||||
// index was created but cleared
|
// index was created but cleared
|
||||||
info!("terminating retry fts thread");
|
info!("terminating retry fts thread");
|
||||||
db::Interface::delete(&s.env, &s.handle, "fts");
|
db::Interface::delete(&s.env, &s.handle, list_key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for m in v {
|
for m in v {
|
||||||
|
@ -438,7 +437,7 @@ pub async fn retry_fts() {
|
||||||
if message.mid != utils::empty_string() {
|
if message.mid != utils::empty_string() {
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
// get jwp from db
|
// get jwp from db
|
||||||
let k = format!("{}-{}", "fts-jwp", &message.to);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &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() {
|
||||||
let m_type = if message.mid.contains("misg") {
|
let m_type = if message.mid.contains("misg") {
|
||||||
|
@ -479,7 +478,7 @@ pub async fn send_prepare_info(orid: &String, contact: &String) {
|
||||||
let wallet_password = utils::empty_string();
|
let wallet_password = utils::empty_string();
|
||||||
monero::open_wallet(&orid, &wallet_password).await;
|
monero::open_wallet(&orid, &wallet_password).await;
|
||||||
let prepare_info = monero::prepare_wallet().await;
|
let prepare_info = monero::prepare_wallet().await;
|
||||||
let k = format!("{}-{}", "fts-jwp", contact);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
let body_str = format!(
|
let body_str = format!(
|
||||||
"{}:{}:{}",
|
"{}:{}:{}",
|
||||||
|
@ -504,7 +503,7 @@ pub async fn send_make_info(orid: &String, contact: &String, info: Vec<String>)
|
||||||
let wallet_password = utils::empty_string();
|
let wallet_password = utils::empty_string();
|
||||||
monero::open_wallet(&orid, &wallet_password).await;
|
monero::open_wallet(&orid, &wallet_password).await;
|
||||||
let make_info = monero::make_wallet(info).await;
|
let make_info = monero::make_wallet(info).await;
|
||||||
let k = format!("{}-{}", "fts-jwp", contact);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
let body_str = format!("{}:{}:{}", MAKE_MSIG, orid, &make_info.result.multisig_info);
|
let body_str = format!("{}:{}:{}", MAKE_MSIG, orid, &make_info.result.multisig_info);
|
||||||
let message: Message = Message {
|
let message: Message = Message {
|
||||||
|
@ -526,7 +525,7 @@ pub async fn send_exchange_info(orid: &String, contact: &String, info: Vec<Strin
|
||||||
let wallet_password = utils::empty_string();
|
let wallet_password = utils::empty_string();
|
||||||
monero::open_wallet(&orid, &wallet_password).await;
|
monero::open_wallet(&orid, &wallet_password).await;
|
||||||
let exchange_info = monero::exchange_multisig_keys(false, info, &wallet_password).await;
|
let exchange_info = monero::exchange_multisig_keys(false, info, &wallet_password).await;
|
||||||
let k = format!("{}-{}", "fts-jwp", contact);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
let body_str = format!(
|
let body_str = format!(
|
||||||
"{}:{}:{}",
|
"{}:{}:{}",
|
||||||
|
@ -551,7 +550,7 @@ pub async fn send_export_info(orid: &String, contact: &String) {
|
||||||
let wallet_password = utils::empty_string();
|
let wallet_password = utils::empty_string();
|
||||||
monero::open_wallet(&orid, &wallet_password).await;
|
monero::open_wallet(&orid, &wallet_password).await;
|
||||||
let exchange_info = monero::export_multisig_info().await;
|
let exchange_info = monero::export_multisig_info().await;
|
||||||
let k = format!("{}-{}", "fts-jwp", contact);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, contact);
|
||||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
let body_str = format!("{}:{}:{}", EXPORT_MSIG, orid, &exchange_info.result.info);
|
let body_str = format!("{}:{}:{}", EXPORT_MSIG, orid, &exchange_info.result.info);
|
||||||
let message: Message = Message {
|
let message: Message = Message {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use log::{
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
enum StatusType {
|
enum StatusType {
|
||||||
|
_Cancelled,
|
||||||
Delivered,
|
Delivered,
|
||||||
MultisigMissing,
|
MultisigMissing,
|
||||||
MulitsigComplete,
|
MulitsigComplete,
|
||||||
|
@ -29,6 +30,7 @@ enum StatusType {
|
||||||
impl StatusType {
|
impl StatusType {
|
||||||
pub fn value(&self) -> String {
|
pub fn value(&self) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
|
StatusType::_Cancelled => String::from("Cancelled"),
|
||||||
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"),
|
||||||
|
@ -45,7 +47,7 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
||||||
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
std::env::var(crate::MONERO_WALLET_PASSWORD).unwrap_or(String::from("password"));
|
||||||
monero::open_wallet(&wallet_name, &wallet_password).await;
|
monero::open_wallet(&wallet_name, &wallet_password).await;
|
||||||
let ts = chrono::offset::Utc::now().timestamp();
|
let ts = chrono::offset::Utc::now().timestamp();
|
||||||
let orid: String = format!("O{}", utils::generate_rnd());
|
let orid: String = format!("{}{}", crate::ORDER_DB_KEY, utils::generate_rnd());
|
||||||
let r_subaddress = monero::create_address().await;
|
let r_subaddress = monero::create_address().await;
|
||||||
let subaddress = r_subaddress.result.address;
|
let subaddress = r_subaddress.result.address;
|
||||||
let new_order = Order {
|
let new_order = Order {
|
||||||
|
@ -71,8 +73,8 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
||||||
let k = &new_order.orid;
|
let k = &new_order.orid;
|
||||||
db::Interface::write(&s.env, &s.handle, k, &Order::to_db(&new_order));
|
db::Interface::write(&s.env, &s.handle, k, &Order::to_db(&new_order));
|
||||||
// in order to retrieve all orders, write keys to with ol
|
// in order to retrieve all orders, write keys to with ol
|
||||||
let list_key = format!("ol");
|
let list_key = crate::ORDER_LIST_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating order index");
|
debug!("creating order index");
|
||||||
}
|
}
|
||||||
|
@ -83,6 +85,23 @@ pub async fn create(j_order: Json<reqres::OrderRequest>) -> Order {
|
||||||
new_order
|
new_order
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Backup order for customer
|
||||||
|
pub fn backup(order: &Order) {
|
||||||
|
info!("creating backup of order: {}", order.orid);
|
||||||
|
let s = db::Interface::open();
|
||||||
|
let k = &order.orid;
|
||||||
|
db::Interface::write(&s.env, &s.handle, k, &Order::to_db(&order));
|
||||||
|
// in order to retrieve all orders, write keys to with col
|
||||||
|
let list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||||
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
|
if r == utils::empty_string() {
|
||||||
|
debug!("creating customer order index");
|
||||||
|
}
|
||||||
|
let order_list = [r, String::from(&order.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);
|
||||||
|
}
|
||||||
|
|
||||||
/// Lookup order
|
/// Lookup order
|
||||||
pub fn find(oid: &String) -> Order {
|
pub fn find(oid: &String) -> Order {
|
||||||
info!("find order: {}", &oid);
|
info!("find order: {}", &oid);
|
||||||
|
@ -98,7 +117,7 @@ pub fn find(oid: &String) -> Order {
|
||||||
/// Lookup all orders from admin server
|
/// Lookup all orders from admin server
|
||||||
pub fn find_all() -> Vec<Order> {
|
pub fn find_all() -> Vec<Order> {
|
||||||
let i_s = db::Interface::open();
|
let i_s = db::Interface::open();
|
||||||
let i_list_key = format!("ol");
|
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
if i_r == utils::empty_string() {
|
if i_r == utils::empty_string() {
|
||||||
error!("order index not found");
|
error!("order index not found");
|
||||||
|
@ -115,11 +134,31 @@ pub fn find_all() -> Vec<Order> {
|
||||||
orders
|
orders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lookup all orders that customer has saved from gui
|
||||||
|
pub fn find_all_backup() -> Vec<Order> {
|
||||||
|
let i_s = db::Interface::open();
|
||||||
|
let i_list_key = crate::CUSTOMER_ORDER_LIST_DB_KEY;
|
||||||
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
|
if i_r == utils::empty_string() {
|
||||||
|
error!("customer 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<Order> = Vec::new();
|
||||||
|
for o in i_v {
|
||||||
|
let order: Order = find(&o);
|
||||||
|
if order.orid != utils::empty_string() {
|
||||||
|
orders.push(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orders
|
||||||
|
}
|
||||||
|
|
||||||
/// Lookup all orders for customer
|
/// Lookup all orders for customer
|
||||||
pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
pub async fn find_all_customer_orders(cid: String) -> Vec<Order> {
|
||||||
info!("lookup orders for customer: {}", &cid);
|
info!("lookup orders for customer: {}", &cid);
|
||||||
let i_s = db::Interface::open();
|
let i_s = db::Interface::open();
|
||||||
let i_list_key = format!("ol");
|
let i_list_key = crate::ORDER_LIST_DB_KEY;
|
||||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
if i_r == utils::empty_string() {
|
if i_r == utils::empty_string() {
|
||||||
error!("order index not found");
|
error!("order index not found");
|
||||||
|
@ -298,7 +337,11 @@ pub async fn finalize_order(orid: &String) -> reqres::FinalizeOrderResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send order request to vendor and start multisig flow
|
/// Send order request to vendor and start multisig flow
|
||||||
pub async fn transmit_order_request(contact: String, jwp: String, request: reqres::OrderRequest) -> Result<Order, Box<dyn Error>> {
|
pub async fn transmit_order_request(
|
||||||
|
contact: String,
|
||||||
|
jwp: String,
|
||||||
|
request: reqres::OrderRequest,
|
||||||
|
) -> Result<Order, 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();
|
||||||
|
@ -313,7 +356,7 @@ pub async fn transmit_order_request(contact: String, jwp: String, request: reqre
|
||||||
let res = response.json::<Order>().await;
|
let res = response.json::<Order>().await;
|
||||||
debug!("create order response: {:?}", res);
|
debug!("create order response: {:?}", res);
|
||||||
match res {
|
match res {
|
||||||
Ok(_r) => Ok(Default::default()),
|
Ok(r) => Ok(r),
|
||||||
_ => Ok(Default::default()),
|
_ => Ok(Default::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use std::error::Error;
|
||||||
|
|
||||||
/// Create a new product
|
/// Create a new product
|
||||||
pub fn create(d: Json<Product>) -> Product {
|
pub fn create(d: Json<Product>) -> Product {
|
||||||
let pid: String = format!("product{}", utils::generate_rnd());
|
let pid: String = format!("{}{}", crate::PRODUCT_DB_KEY, utils::generate_rnd());
|
||||||
if !validate_product(&d) {
|
if !validate_product(&d) {
|
||||||
error!("invalid product");
|
error!("invalid product");
|
||||||
return Default::default();
|
return Default::default();
|
||||||
|
@ -33,8 +33,8 @@ pub fn create(d: Json<Product>) -> Product {
|
||||||
let k = &new_product.pid;
|
let k = &new_product.pid;
|
||||||
db::Interface::write(&s.env, &s.handle, k, &Product::to_db(&new_product));
|
db::Interface::write(&s.env, &s.handle, k, &Product::to_db(&new_product));
|
||||||
// in order to retrieve all products, write keys to with pl
|
// in order to retrieve all products, write keys to with pl
|
||||||
let list_key = format!("pl");
|
let list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(list_key));
|
||||||
if r == utils::empty_string() {
|
if r == utils::empty_string() {
|
||||||
debug!("creating product index");
|
debug!("creating product index");
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ pub fn find(pid: &String) -> Product {
|
||||||
/// Product lookup for all
|
/// Product lookup for all
|
||||||
pub fn find_all() -> Vec<Product> {
|
pub fn find_all() -> Vec<Product> {
|
||||||
let i_s = db::Interface::open();
|
let i_s = db::Interface::open();
|
||||||
let i_list_key = format!("pl");
|
let i_list_key = crate::PRODUCT_LIST_DB_KEY;
|
||||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
if i_r == utils::empty_string() {
|
if i_r == utils::empty_string() {
|
||||||
error!("product index not found");
|
error!("product index not found");
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub async fn prove_payment(contact: String, txp: &TxProof) -> Result<reqres::Jwp
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
// cache the jwp for for fts
|
// cache the jwp for for fts
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
let k = format!("{}-{}", "fts-jwp", &contact);
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||||
db::Interface::delete(&s.env, &s.handle, &k);
|
db::Interface::delete(&s.env, &s.handle, &k);
|
||||||
db::Interface::write(&s.env, &s.handle, &k, &r.jwp);
|
db::Interface::write(&s.env, &s.handle, &k, &r.jwp);
|
||||||
Ok(r)
|
Ok(r)
|
||||||
|
|
|
@ -12,10 +12,12 @@ use log::{
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
// This module is only used for remote access
|
// This module is only used for remote access
|
||||||
|
// TODO(c2m): remove this module since there is only support for a single
|
||||||
|
// authenticated user
|
||||||
|
|
||||||
/// Create a new user
|
/// Create a new user
|
||||||
pub fn create(address: &String) -> User {
|
pub fn create(address: &String) -> User {
|
||||||
let f_uid: String = format!("u{}", utils::generate_rnd());
|
let f_uid: String = format!("{}{}", crate::USER_DB_KEY, utils::generate_rnd());
|
||||||
let new_user = User {
|
let new_user = User {
|
||||||
uid: String::from(&f_uid),
|
uid: String::from(&f_uid),
|
||||||
xmr_address: String::from(address),
|
xmr_address: String::from(address),
|
||||||
|
|
|
@ -336,9 +336,9 @@ impl eframe::App for AddressBookApp {
|
||||||
if ui.button("Sign Key").clicked() {
|
if ui.button("Sign Key").clicked() {
|
||||||
contact::trust_gpg(self.status.i2p.clone());
|
contact::trust_gpg(self.status.i2p.clone());
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-signed-key"),
|
String::from(crate::GUI_SIGNED_GPG_DB_KEY),
|
||||||
self.status.i2p.clone(),
|
self.status.i2p.clone(),
|
||||||
String::from("1"),
|
String::from(crate::SIGNED_GPG_KEY),
|
||||||
);
|
);
|
||||||
self.showing_status = false;
|
self.showing_status = false;
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ impl eframe::App for AddressBookApp {
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
if ui.button("Check Status").clicked() {
|
if ui.button("Check Status").clicked() {
|
||||||
let nick_db = utils::search_gui_db(
|
let nick_db = utils::search_gui_db(
|
||||||
String::from("gui-nick"),
|
String::from(crate::GUI_NICK_DB_KEY),
|
||||||
String::from(&c.i2p_address),
|
String::from(&c.i2p_address),
|
||||||
);
|
);
|
||||||
let nick = if nick_db == utils::empty_string() {
|
let nick = if nick_db == utils::empty_string() {
|
||||||
|
@ -554,16 +554,16 @@ impl eframe::App for AddressBookApp {
|
||||||
self.status.i2p = String::from(&c.i2p_address);
|
self.status.i2p = String::from(&c.i2p_address);
|
||||||
// get the txp
|
// get the txp
|
||||||
self.status.txp = utils::search_gui_db(
|
self.status.txp = utils::search_gui_db(
|
||||||
String::from("gui-txp"),
|
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||||
String::from(&c.i2p_address),
|
String::from(&c.i2p_address),
|
||||||
);
|
);
|
||||||
// get the jwp
|
// get the jwp
|
||||||
self.status.jwp = utils::search_gui_db(
|
self.status.jwp = utils::search_gui_db(
|
||||||
String::from("gui-jwp"),
|
String::from(crate::GUI_JWP_DB_KEY),
|
||||||
String::from(&c.i2p_address),
|
String::from(&c.i2p_address),
|
||||||
);
|
);
|
||||||
let r_exp = utils::search_gui_db(
|
let r_exp = utils::search_gui_db(
|
||||||
String::from("gui-exp"),
|
String::from(crate::GUI_EXP_DB_KEY),
|
||||||
String::from(&c.i2p_address),
|
String::from(&c.i2p_address),
|
||||||
);
|
);
|
||||||
self.status.exp = r_exp;
|
self.status.exp = r_exp;
|
||||||
|
@ -713,22 +713,22 @@ fn send_payment_req(
|
||||||
signature: get_txp.result.signature,
|
signature: get_txp.result.signature,
|
||||||
};
|
};
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-txp"),
|
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&ftxp.signature),
|
String::from(&ftxp.signature),
|
||||||
);
|
);
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-txp-hash"),
|
String::from(crate::GUI_TX_HASH_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&ftxp.hash),
|
String::from(&ftxp.hash),
|
||||||
);
|
);
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-txp-sig"),
|
String::from(crate::GUI_TX_SIGNATURE_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&ftxp.signature),
|
String::from(&ftxp.signature),
|
||||||
);
|
);
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-txp-subaddress"),
|
String::from(crate::GUI_TX_SUBADDRESS_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&ftxp.subaddress),
|
String::from(&ftxp.subaddress),
|
||||||
);
|
);
|
||||||
|
@ -746,7 +746,7 @@ fn send_payment_req(
|
||||||
match proof::prove_payment(String::from(&contact), &ftxp).await {
|
match proof::prove_payment(String::from(&contact), &ftxp).await {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-jwp"),
|
String::from(crate::GUI_JWP_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&result.jwp),
|
String::from(&result.jwp),
|
||||||
);
|
);
|
||||||
|
@ -754,7 +754,7 @@ fn send_payment_req(
|
||||||
let seconds: i64 = expire as i64 * 2 * 60;
|
let seconds: i64 = expire as i64 * 2 * 60;
|
||||||
let unix: i64 = chrono::offset::Utc::now().timestamp() + seconds;
|
let unix: i64 = chrono::offset::Utc::now().timestamp() + seconds;
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-exp"),
|
String::from(crate::GUI_EXP_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
format!("{}", unix),
|
format!("{}", unix),
|
||||||
);
|
);
|
||||||
|
@ -767,9 +767,9 @@ fn send_payment_req(
|
||||||
monero::close_wallet(&wallet_name, &wallet_password).await;
|
monero::close_wallet(&wallet_name, &wallet_password).await;
|
||||||
}
|
}
|
||||||
if retry {
|
if retry {
|
||||||
let k_hash = String::from("gui-txp-hash");
|
let k_hash = String::from(crate::GUI_TX_HASH_DB_KEY);
|
||||||
let k_sig = String::from("gui-txp-sig");
|
let k_sig = String::from(crate::GUI_TX_SIGNATURE_DB_KEY);
|
||||||
let k_subaddress = String::from("gui-txp-subaddress");
|
let k_subaddress = String::from(crate::GUI_TX_SUBADDRESS_DB_KEY);
|
||||||
let hash = utils::search_gui_db(k_hash, String::from(&contact));
|
let hash = utils::search_gui_db(k_hash, String::from(&contact));
|
||||||
let signature = utils::search_gui_db(k_sig, String::from(&contact));
|
let signature = utils::search_gui_db(k_sig, String::from(&contact));
|
||||||
let subaddress = utils::search_gui_db(k_subaddress, String::from(&contact));
|
let subaddress = utils::search_gui_db(k_subaddress, String::from(&contact));
|
||||||
|
@ -788,7 +788,7 @@ fn send_payment_req(
|
||||||
match proof::prove_payment(String::from(&contact), &ftxp).await {
|
match proof::prove_payment(String::from(&contact), &ftxp).await {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
utils::write_gui_db(
|
utils::write_gui_db(
|
||||||
String::from("gui-jwp"),
|
String::from(crate::GUI_JWP_DB_KEY),
|
||||||
String::from(&contact),
|
String::from(&contact),
|
||||||
String::from(&result.jwp),
|
String::from(&result.jwp),
|
||||||
);
|
);
|
||||||
|
@ -825,14 +825,18 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_signed_key(contact: String) -> bool {
|
fn check_signed_key(contact: String) -> bool {
|
||||||
let v = utils::search_gui_db(String::from("gui-signed-key"), contact);
|
let v = utils::search_gui_db(String::from(crate::GUI_SIGNED_GPG_DB_KEY), contact);
|
||||||
v != utils::empty_string()
|
v != utils::empty_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_nick_req(contact: String, nick: String) {
|
fn change_nick_req(contact: String, nick: String) {
|
||||||
log::debug!("change nick");
|
log::debug!("change nick");
|
||||||
utils::clear_gui_db(String::from("gui-nick"), String::from(&contact));
|
utils::clear_gui_db(String::from(crate::GUI_NICK_DB_KEY), String::from(&contact));
|
||||||
utils::write_gui_db(String::from("gui-nick"), String::from(&contact), nick);
|
utils::write_gui_db(
|
||||||
|
String::from(crate::GUI_NICK_DB_KEY),
|
||||||
|
String::from(&contact),
|
||||||
|
nick,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_can_transfer_req(tx: Sender<bool>, ctx: egui::Context, invoice: u128) {
|
fn send_can_transfer_req(tx: Sender<bool>, ctx: egui::Context, invoice: u128) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub struct MarketApp {
|
||||||
contact_info_rx: Receiver<models::Contact>,
|
contact_info_rx: Receiver<models::Contact>,
|
||||||
contact_timeout_tx: Sender<bool>,
|
contact_timeout_tx: Sender<bool>,
|
||||||
contact_timeout_rx: Receiver<bool>,
|
contact_timeout_rx: Receiver<bool>,
|
||||||
|
customer_orders: Vec<models::Order>,
|
||||||
find_vendor: String,
|
find_vendor: String,
|
||||||
get_vendor_products_tx: Sender<Vec<models::Product>>,
|
get_vendor_products_tx: Sender<Vec<models::Product>>,
|
||||||
get_vendor_products_rx: Receiver<Vec<models::Product>>,
|
get_vendor_products_rx: Receiver<Vec<models::Product>>,
|
||||||
|
@ -17,6 +18,8 @@ pub struct MarketApp {
|
||||||
is_loading: bool,
|
is_loading: bool,
|
||||||
is_ordering: bool,
|
is_ordering: bool,
|
||||||
is_pinging: bool,
|
is_pinging: bool,
|
||||||
|
is_customer_viewing_orders: bool,
|
||||||
|
is_managing_multisig: bool,
|
||||||
is_product_image_set: bool,
|
is_product_image_set: bool,
|
||||||
is_showing_products: bool,
|
is_showing_products: bool,
|
||||||
is_showing_product_image: bool,
|
is_showing_product_image: bool,
|
||||||
|
@ -69,12 +72,15 @@ impl Default for MarketApp {
|
||||||
contact_info_tx,
|
contact_info_tx,
|
||||||
contact_timeout_rx,
|
contact_timeout_rx,
|
||||||
contact_timeout_tx,
|
contact_timeout_tx,
|
||||||
|
customer_orders: Vec::new(),
|
||||||
find_vendor: utils::empty_string(),
|
find_vendor: utils::empty_string(),
|
||||||
get_vendor_products_rx,
|
get_vendor_products_rx,
|
||||||
get_vendor_products_tx,
|
get_vendor_products_tx,
|
||||||
get_vendor_product_rx,
|
get_vendor_product_rx,
|
||||||
get_vendor_product_tx,
|
get_vendor_product_tx,
|
||||||
|
is_customer_viewing_orders: false,
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
|
is_managing_multisig: false,
|
||||||
is_ordering: false,
|
is_ordering: false,
|
||||||
is_pinging: false,
|
is_pinging: false,
|
||||||
is_product_image_set: false,
|
is_product_image_set: false,
|
||||||
|
@ -185,6 +191,152 @@ impl eframe::App for MarketApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vendor status window
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
let mut is_showing_vendor_status = self.is_showing_vendor_status;
|
||||||
|
egui::Window::new(&self.vendor_status.i2p)
|
||||||
|
.open(&mut is_showing_vendor_status)
|
||||||
|
.vscroll(true)
|
||||||
|
.title_bar(false)
|
||||||
|
.id(egui::Id::new(self.vendor_status.i2p.clone()))
|
||||||
|
.show(&ctx, |ui| {
|
||||||
|
if self.is_pinging {
|
||||||
|
ui.add(egui::Spinner::new());
|
||||||
|
ui.label("pinging...");
|
||||||
|
}
|
||||||
|
let status = if self.s_contact.xmr_address != utils::empty_string() {
|
||||||
|
"online"
|
||||||
|
} else {
|
||||||
|
"offline"
|
||||||
|
};
|
||||||
|
let mode = if self.vendor_status.is_vendor {
|
||||||
|
"enabled "
|
||||||
|
} else {
|
||||||
|
"disabled"
|
||||||
|
};
|
||||||
|
ui.label(format!("status: {}", status));
|
||||||
|
ui.label(format!("vendor mode: {}", mode));
|
||||||
|
ui.label(format!("nick: {}", self.vendor_status.nick));
|
||||||
|
ui.label(format!("tx proof: {}", self.vendor_status.txp));
|
||||||
|
ui.label(format!("jwp: {}", self.vendor_status.jwp));
|
||||||
|
ui.label(format!("expiration: {}", self.vendor_status.h_exp));
|
||||||
|
ui.label(format!("signed key: {}", self.vendor_status.signed_key));
|
||||||
|
if ui.button("Exit").clicked() {
|
||||||
|
self.is_showing_vendor_status = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Product image window
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
let mut is_showing_product_image = self.is_showing_product_image;
|
||||||
|
egui::Window::new("")
|
||||||
|
.open(&mut is_showing_product_image)
|
||||||
|
.vscroll(true)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
self.product_image.show(ui);
|
||||||
|
if ui.button("Exit").clicked() {
|
||||||
|
self.is_showing_product_image = false;
|
||||||
|
self.is_product_image_set = false;
|
||||||
|
let read_product_image = std::fs::read("./assets/qr.png").unwrap_or(Vec::new());
|
||||||
|
self.product_image =
|
||||||
|
egui_extras::RetainedImage::from_image_bytes("qr.png", &read_product_image)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Multisig Management window
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
let mut is_managing_multisig = self.is_managing_multisig;
|
||||||
|
egui::Window::new("Multisig Management")
|
||||||
|
.open(&mut is_managing_multisig)
|
||||||
|
.vscroll(true)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
// TODO(c2m): interactive multisig checklist
|
||||||
|
if ui.button("Exit").clicked() {
|
||||||
|
self.is_managing_multisig = false;
|
||||||
|
self.is_loading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// View orders - Customer Order Flow Management
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
let mut is_customer_viewing_orders = self.is_customer_viewing_orders;
|
||||||
|
egui::Window::new("View Orders")
|
||||||
|
.open(&mut is_customer_viewing_orders)
|
||||||
|
.vscroll(true)
|
||||||
|
.show(&ctx, |ui| {
|
||||||
|
use egui_extras::{
|
||||||
|
Column,
|
||||||
|
TableBuilder,
|
||||||
|
};
|
||||||
|
let table = TableBuilder::new(ui)
|
||||||
|
.striped(true)
|
||||||
|
.resizable(true)
|
||||||
|
.cell_layout(egui::Layout::left_to_right(egui::Align::Center))
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::auto())
|
||||||
|
.column(Column::auto())
|
||||||
|
.min_scrolled_height(0.0);
|
||||||
|
|
||||||
|
table
|
||||||
|
.header(20.0, |mut header| {
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.strong("orid");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.strong("date");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.strong("status");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.strong("");
|
||||||
|
});
|
||||||
|
header.col(|ui| {
|
||||||
|
ui.strong("");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.body(|mut body| {
|
||||||
|
for o in &self.customer_orders {
|
||||||
|
let row_height = 20.0;
|
||||||
|
body.row(row_height, |mut row| {
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label(format!("{}", o.orid));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
let h_date =
|
||||||
|
chrono::NaiveDateTime::from_timestamp_opt(o.date, 0)
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
ui.label(format!("{}", h_date));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.label(format!("{}", o.status));
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
if ui.button("MSIG").clicked() {
|
||||||
|
// dynamically generate buttons for multisig wallet ops
|
||||||
|
}
|
||||||
|
});
|
||||||
|
row.col(|ui| {
|
||||||
|
ui.style_mut().wrap = Some(false);
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
if ui.button("Cancel").clicked() {
|
||||||
|
// TODO(c2m): Cancel order logic
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if ui.button("Exit").clicked() {
|
||||||
|
self.is_customer_viewing_orders = false;
|
||||||
|
self.is_loading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Customer Order Form
|
// Customer Order Form
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
let mut is_ordering = self.is_ordering;
|
let mut is_ordering = self.is_ordering;
|
||||||
|
@ -192,6 +344,10 @@ impl eframe::App for MarketApp {
|
||||||
.open(&mut is_ordering)
|
.open(&mut is_ordering)
|
||||||
.vscroll(true)
|
.vscroll(true)
|
||||||
.show(&ctx, |ui| {
|
.show(&ctx, |ui| {
|
||||||
|
if self.is_loading {
|
||||||
|
ui.add(egui::Spinner::new());
|
||||||
|
ui.label("loading...");
|
||||||
|
}
|
||||||
ui.label(format!("cid: {}", self.new_order.cid));
|
ui.label(format!("cid: {}", self.new_order.cid));
|
||||||
ui.label(format!("pid: {}", self.new_order.pid));
|
ui.label(format!("pid: {}", self.new_order.pid));
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
@ -200,7 +356,7 @@ impl eframe::App for MarketApp {
|
||||||
.labelled_by(shipping_name.id);
|
.labelled_by(shipping_name.id);
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
let qty_name = ui.label("quantity: \t\t");
|
let qty_name = ui.label("quantity: \t\t\t\t");
|
||||||
ui.text_edit_singleline(&mut self.new_order_quantity)
|
ui.text_edit_singleline(&mut self.new_order_quantity)
|
||||||
.labelled_by(qty_name.id);
|
.labelled_by(qty_name.id);
|
||||||
});
|
});
|
||||||
|
@ -235,13 +391,12 @@ impl eframe::App for MarketApp {
|
||||||
self.vendor_status.i2p.clone(),
|
self.vendor_status.i2p.clone(),
|
||||||
ctx.clone(),
|
ctx.clone(),
|
||||||
self.vendor_status.jwp.clone(),
|
self.vendor_status.jwp.clone(),
|
||||||
new_order
|
new_order,
|
||||||
);
|
);
|
||||||
self.new_order = Default::default();
|
self.new_order = Default::default();
|
||||||
self.new_order_price = 0;
|
self.new_order_price = 0;
|
||||||
self.new_order_quantity = utils::empty_string();
|
self.new_order_quantity = utils::empty_string();
|
||||||
self.new_order_shipping_address = utils::empty_string();
|
self.new_order_shipping_address = utils::empty_string();
|
||||||
self.is_ordering = false;
|
|
||||||
self.is_showing_products = false;
|
self.is_showing_products = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +468,7 @@ impl eframe::App for MarketApp {
|
||||||
row.col(|ui| {
|
row.col(|ui| {
|
||||||
if ui.button("Check Status").clicked() {
|
if ui.button("Check Status").clicked() {
|
||||||
let nick_db = utils::search_gui_db(
|
let nick_db = utils::search_gui_db(
|
||||||
String::from("gui-nick"),
|
String::from(crate::GUI_NICK_DB_KEY),
|
||||||
String::from(&v.i2p_address),
|
String::from(&v.i2p_address),
|
||||||
);
|
);
|
||||||
let nick = if nick_db == utils::empty_string() {
|
let nick = if nick_db == utils::empty_string() {
|
||||||
|
@ -325,17 +480,16 @@ impl eframe::App for MarketApp {
|
||||||
self.vendor_status.i2p = String::from(&v.i2p_address);
|
self.vendor_status.i2p = String::from(&v.i2p_address);
|
||||||
// get the txp
|
// get the txp
|
||||||
self.vendor_status.txp = utils::search_gui_db(
|
self.vendor_status.txp = utils::search_gui_db(
|
||||||
String::from("gui-txp"),
|
String::from(crate::GUI_TX_PROOF_DB_KEY),
|
||||||
String::from(&v.i2p_address),
|
String::from(&v.i2p_address),
|
||||||
);
|
);
|
||||||
// get the jwp
|
// get the jwp
|
||||||
self.vendor_status.jwp = utils::search_gui_db(
|
self.vendor_status.jwp = utils::search_gui_db(
|
||||||
String::from("gui-jwp"),
|
String::from(crate::GUI_JWP_DB_KEY),
|
||||||
String::from(&v.i2p_address),
|
String::from(&v.i2p_address),
|
||||||
);
|
);
|
||||||
log::debug!("jwp: {}", self.vendor_status.jwp);
|
|
||||||
let r_exp = utils::search_gui_db(
|
let r_exp = utils::search_gui_db(
|
||||||
String::from("gui-exp"),
|
String::from(crate::GUI_EXP_DB_KEY),
|
||||||
String::from(&v.i2p_address),
|
String::from(&v.i2p_address),
|
||||||
);
|
);
|
||||||
self.vendor_status.exp = r_exp;
|
self.vendor_status.exp = r_exp;
|
||||||
|
@ -686,10 +840,10 @@ impl eframe::App for MarketApp {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(c2m): Orders window
|
// Vendor Orders window
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
let mut is_showing_orders = self.is_showing_orders;
|
let mut is_showing_orders = self.is_showing_orders;
|
||||||
egui::Window::new("Orders")
|
egui::Window::new("Manage Orders")
|
||||||
.open(&mut is_showing_orders)
|
.open(&mut is_showing_orders)
|
||||||
.vscroll(true)
|
.vscroll(true)
|
||||||
.show(&ctx, |ui| {
|
.show(&ctx, |ui| {
|
||||||
|
@ -781,7 +935,8 @@ impl eframe::App for MarketApp {
|
||||||
}
|
}
|
||||||
ui.label("\n");
|
ui.label("\n");
|
||||||
if ui.button("View Orders").clicked() {
|
if ui.button("View Orders").clicked() {
|
||||||
// TODO(c2m):
|
self.customer_orders = order::find_all_backup();
|
||||||
|
self.is_customer_viewing_orders = true;
|
||||||
}
|
}
|
||||||
if self.is_vendor_enabled {
|
if self.is_vendor_enabled {
|
||||||
ui.label("\n");
|
ui.label("\n");
|
||||||
|
@ -850,6 +1005,10 @@ impl eframe::App for MarketApp {
|
||||||
self.is_showing_products = true;
|
self.is_showing_products = true;
|
||||||
self.is_showing_vendors = false;
|
self.is_showing_vendors = false;
|
||||||
}
|
}
|
||||||
|
ui.label("\n");
|
||||||
|
if ui.button("Manage Orders").clicked() {
|
||||||
|
// TODO(c2m): vendor order management logic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -884,7 +1043,7 @@ fn send_contact_info_req(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_signed_key(contact: String) -> bool {
|
fn check_signed_key(contact: String) -> bool {
|
||||||
let v = utils::search_gui_db(String::from("gui-signed-key"), contact);
|
let v = utils::search_gui_db(String::from(crate::GUI_SIGNED_GPG_DB_KEY), contact);
|
||||||
v != utils::empty_string()
|
v != utils::empty_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,18 +1096,20 @@ fn vendor_status_timeout(tx: Sender<bool>, ctx: egui::Context) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit_order_req(tx: Sender<models::Order>, contact: String, ctx: egui::Context, jwp: String, request: reqres::OrderRequest) {
|
fn submit_order_req(
|
||||||
|
tx: Sender<models::Order>,
|
||||||
|
contact: String,
|
||||||
|
ctx: egui::Context,
|
||||||
|
jwp: String,
|
||||||
|
request: reqres::OrderRequest,
|
||||||
|
) {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
log::info!("submit order");
|
log::info!("submit order");
|
||||||
let r_contact = String::from(&contact);
|
let r_contact = String::from(&contact);
|
||||||
let order = order::transmit_order_request(r_contact, jwp, request).await;
|
let order = order::transmit_order_request(r_contact, jwp, request).await;
|
||||||
let u_order = order.unwrap_or(Default::default());
|
let u_order = order.unwrap_or_else(|_| Default::default());
|
||||||
// cache order request to db
|
// cache order request to db
|
||||||
utils::write_gui_db(
|
order::backup(&u_order);
|
||||||
String::from("gui-orid"),
|
|
||||||
String::from(&contact),
|
|
||||||
String::from(&u_order.orid),
|
|
||||||
);
|
|
||||||
let _ = tx.send(u_order);
|
let _ = tx.send(u_order);
|
||||||
ctx.request_repaint();
|
ctx.request_repaint();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,20 @@ mod apps;
|
||||||
mod login;
|
mod login;
|
||||||
mod wrap_app;
|
mod wrap_app;
|
||||||
|
|
||||||
|
// LMDB keys
|
||||||
|
pub const GUI_JWP_DB_KEY: &str = "gui-jwp";
|
||||||
|
pub const GUI_EXP_DB_KEY: &str = "gui-exp";
|
||||||
|
pub const GUI_TX_PROOF_DB_KEY: &str = "gui-txp";
|
||||||
|
pub const GUI_NICK_DB_KEY: &str = "gui-nick";
|
||||||
|
pub const GUI_TX_SIGNATURE_DB_KEY: &str = "gui-txp-sig";
|
||||||
|
pub const GUI_TX_HASH_DB_KEY: &str = "gui-txp-hash";
|
||||||
|
pub const GUI_SIGNED_GPG_DB_KEY: &str = "gui-signed-key";
|
||||||
|
pub const GUI_TX_SUBADDRESS_DB_KEY: &str = "gui-txp-subaddress";
|
||||||
|
// End LMDB keys
|
||||||
|
|
||||||
|
/// Designate a contact as verified and trusted
|
||||||
|
pub const SIGNED_GPG_KEY: &str = "1";
|
||||||
|
|
||||||
/// key for fetching the login credential hash
|
/// key for fetching the login credential hash
|
||||||
pub const CREDENTIAL_KEY: &str = "NEVEKO_GUI_KEY";
|
pub const CREDENTIAL_KEY: &str = "NEVEKO_GUI_KEY";
|
||||||
/// TODO(c2m): configurable lock screen timeout
|
/// TODO(c2m): configurable lock screen timeout
|
||||||
|
|
Loading…
Reference in a new issue