mirror of
https://github.com/mimblewimble/mwixnet.git
synced 2025-02-01 17:01:11 +03:00
support api secrets, handle SIGQUIT, SIGINT, and SIGTERM
This commit is contained in:
parent
40bf97a841
commit
e902f78e32
8 changed files with 132 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2475,6 +2475,7 @@ dependencies = [
|
||||||
"bytes 0.5.6",
|
"bytes 0.5.6",
|
||||||
"chacha20",
|
"chacha20",
|
||||||
"clap",
|
"clap",
|
||||||
|
"dirs",
|
||||||
"failure",
|
"failure",
|
||||||
"futures 0.3.17",
|
"futures 0.3.17",
|
||||||
"grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)",
|
"grin_api 5.2.0-alpha.1 (git+https://github.com/mimblewimble/grin)",
|
||||||
|
|
|
@ -11,6 +11,7 @@ byteorder = "1"
|
||||||
bytes = "0.5.6"
|
bytes = "0.5.6"
|
||||||
chacha20 = "0.8.1"
|
chacha20 = "0.8.1"
|
||||||
clap = { version = "2.33", features = ["yaml"] }
|
clap = { version = "2.33", features = ["yaml"] }
|
||||||
|
dirs = "2.0"
|
||||||
failure = "0.1.8"
|
failure = "0.1.8"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
hmac = { version = "0.12.0", features = ["std"]}
|
hmac = { version = "0.12.0", features = ["std"]}
|
||||||
|
|
|
@ -13,11 +13,19 @@ args:
|
||||||
short: n
|
short: n
|
||||||
long: grin_node_url
|
long: grin_node_url
|
||||||
takes_value: true
|
takes_value: true
|
||||||
|
- grin_node_secret_path:
|
||||||
|
help: Path to a file containing the secret for the GRIN node api
|
||||||
|
long: grin_node_secret_path
|
||||||
|
takes_value: true
|
||||||
- wallet_owner_url:
|
- wallet_owner_url:
|
||||||
help: Api address of running wallet owner listener
|
help: Api address of running wallet owner listener
|
||||||
short: l
|
short: l
|
||||||
long: wallet_owner_url
|
long: wallet_owner_url
|
||||||
takes_value: true
|
takes_value: true
|
||||||
|
- wallet_owner_secret_path:
|
||||||
|
help: Path to a file containing the secret for the wallet owner api
|
||||||
|
long: wallet_owner_secret_path
|
||||||
|
takes_value: true
|
||||||
- wallet_pass:
|
- wallet_pass:
|
||||||
help: The wallet's password
|
help: The wallet's password
|
||||||
long: wallet_pass
|
long: wallet_pass
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::{self, Result};
|
||||||
use crate::secp::SecretKey;
|
use crate::secp::SecretKey;
|
||||||
|
|
||||||
use core::num::NonZeroU32;
|
use core::num::NonZeroU32;
|
||||||
use grin_util::{ToHex, ZeroingString};
|
use grin_util::{file, ToHex, ZeroingString};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use ring::{aead, pbkdf2};
|
use ring::{aead, pbkdf2};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
@ -11,6 +11,11 @@ use std::io::prelude::*;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const GRIN_HOME: &str = ".grin";
|
||||||
|
const CHAIN_NAME: &str = "main";
|
||||||
|
const NODE_API_SECRET_FILE_NAME: &str = ".api_secret";
|
||||||
|
const WALLET_OWNER_API_SECRET_FILE_NAME: &str = ".owner_api_secret";
|
||||||
|
|
||||||
/// The decrypted server config to be passed around and used by the rest of the mwixnet code
|
/// The decrypted server config to be passed around and used by the rest of the mwixnet code
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
|
@ -22,8 +27,22 @@ pub struct ServerConfig {
|
||||||
pub addr: SocketAddr,
|
pub addr: SocketAddr,
|
||||||
/// foreign api address of the grin node
|
/// foreign api address of the grin node
|
||||||
pub grin_node_url: SocketAddr,
|
pub grin_node_url: SocketAddr,
|
||||||
|
/// path to file containing api secret for the grin node
|
||||||
|
pub grin_node_secret_path: Option<String>,
|
||||||
/// owner api address of the grin wallet
|
/// owner api address of the grin wallet
|
||||||
pub wallet_owner_url: SocketAddr,
|
pub wallet_owner_url: SocketAddr,
|
||||||
|
/// path to file containing secret for the grin wallet's owner api
|
||||||
|
pub wallet_owner_secret_path: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServerConfig {
|
||||||
|
pub fn node_api_secret(&self) -> Option<String> {
|
||||||
|
file::get_first_line(self.grin_node_secret_path.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wallet_owner_api_secret(&self) -> Option<String> {
|
||||||
|
file::get_first_line(self.wallet_owner_secret_path.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encrypted server key, for storing on disk and decrypting with a password.
|
/// Encrypted server key, for storing on disk and decrypting with a password.
|
||||||
|
@ -134,7 +153,9 @@ struct RawConfig {
|
||||||
interval_s: u32,
|
interval_s: u32,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
grin_node_url: SocketAddr,
|
grin_node_url: SocketAddr,
|
||||||
|
grin_node_secret_path: Option<String>,
|
||||||
wallet_owner_url: SocketAddr,
|
wallet_owner_url: SocketAddr,
|
||||||
|
wallet_owner_secret_path: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the server config to the config_path given, encrypting the server_key first.
|
/// Writes the server config to the config_path given, encrypting the server_key first.
|
||||||
|
@ -152,7 +173,9 @@ pub fn write_config(
|
||||||
interval_s: server_config.interval_s,
|
interval_s: server_config.interval_s,
|
||||||
addr: server_config.addr,
|
addr: server_config.addr,
|
||||||
grin_node_url: server_config.grin_node_url,
|
grin_node_url: server_config.grin_node_url,
|
||||||
|
grin_node_secret_path: server_config.grin_node_secret_path.clone(),
|
||||||
wallet_owner_url: server_config.wallet_owner_url,
|
wallet_owner_url: server_config.wallet_owner_url,
|
||||||
|
wallet_owner_secret_path: server_config.wallet_owner_secret_path.clone(),
|
||||||
};
|
};
|
||||||
let encoded: String = toml::to_string(&raw_config).map_err(|e| {
|
let encoded: String = toml::to_string(&raw_config).map_err(|e| {
|
||||||
error::ErrorKind::SaveConfigError(format!("Error while encoding config as toml: {}", e))
|
error::ErrorKind::SaveConfigError(format!("Error while encoding config as toml: {}", e))
|
||||||
|
@ -189,10 +212,34 @@ pub fn load_config(config_path: &PathBuf, password: &ZeroingString) -> Result<Se
|
||||||
interval_s: raw_config.interval_s,
|
interval_s: raw_config.interval_s,
|
||||||
addr: raw_config.addr,
|
addr: raw_config.addr,
|
||||||
grin_node_url: raw_config.grin_node_url,
|
grin_node_url: raw_config.grin_node_url,
|
||||||
|
grin_node_secret_path: raw_config.grin_node_secret_path,
|
||||||
wallet_owner_url: raw_config.wallet_owner_url,
|
wallet_owner_url: raw_config.wallet_owner_url,
|
||||||
|
wallet_owner_secret_path: raw_config.wallet_owner_secret_path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_grin_path() -> PathBuf {
|
||||||
|
let mut grin_path = match dirs::home_dir() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => PathBuf::new(),
|
||||||
|
};
|
||||||
|
grin_path.push(GRIN_HOME);
|
||||||
|
grin_path.push(CHAIN_NAME);
|
||||||
|
grin_path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_secret_path() -> PathBuf {
|
||||||
|
let mut path = get_grin_path();
|
||||||
|
path.push(NODE_API_SECRET_FILE_NAME);
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wallet_owner_secret_path() -> PathBuf {
|
||||||
|
let mut path = get_grin_path();
|
||||||
|
path.push(WALLET_OWNER_API_SECRET_FILE_NAME);
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
75
src/main.rs
75
src/main.rs
|
@ -1,13 +1,10 @@
|
||||||
use config::ServerConfig;
|
use config::ServerConfig;
|
||||||
use error::{Error, ErrorKind};
|
|
||||||
use node::HttpGrinNode;
|
use node::HttpGrinNode;
|
||||||
use wallet::HttpWallet;
|
use wallet::HttpWallet;
|
||||||
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use grin_util::{StopState, ZeroingString};
|
use grin_util::{StopState, ZeroingString};
|
||||||
use rpassword;
|
use rpassword;
|
||||||
use std::env;
|
|
||||||
use std::io::{self, Write};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
@ -41,9 +38,9 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let config_path = match args.value_of("config_file") {
|
let config_path = match args.value_of("config_file") {
|
||||||
Some(path) => PathBuf::from(path),
|
Some(path) => PathBuf::from(path),
|
||||||
None => {
|
None => {
|
||||||
let mut current_dir = env::current_dir()?;
|
let mut grin_path = config::get_grin_path();
|
||||||
current_dir.push("mwixnet-config.toml");
|
grin_path.push("mwixnet-config.toml");
|
||||||
current_dir
|
grin_path
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +49,9 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.map(|t| t.parse::<u32>().unwrap());
|
.map(|t| t.parse::<u32>().unwrap());
|
||||||
let bind_addr = args.value_of("bind_addr");
|
let bind_addr = args.value_of("bind_addr");
|
||||||
let grin_node_url = args.value_of("grin_node_url");
|
let grin_node_url = args.value_of("grin_node_url");
|
||||||
|
let grin_node_secret_path = args.value_of("grin_node_secret_path");
|
||||||
let wallet_owner_url = args.value_of("wallet_owner_url");
|
let wallet_owner_url = args.value_of("wallet_owner_url");
|
||||||
|
let wallet_owner_secret_path = args.value_of("wallet_owner_secret_path");
|
||||||
|
|
||||||
// Write a new config file if init-config command is supplied
|
// Write a new config file if init-config command is supplied
|
||||||
if let ("init-config", Some(_)) = args.subcommand() {
|
if let ("init-config", Some(_)) = args.subcommand() {
|
||||||
|
@ -68,7 +67,17 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
interval_s: round_time.unwrap_or(DEFAULT_INTERVAL),
|
interval_s: round_time.unwrap_or(DEFAULT_INTERVAL),
|
||||||
addr: bind_addr.unwrap_or("0.0.0.0:3000").parse()?,
|
addr: bind_addr.unwrap_or("0.0.0.0:3000").parse()?,
|
||||||
grin_node_url: grin_node_url.unwrap_or("127.0.0.1:3413").parse()?,
|
grin_node_url: grin_node_url.unwrap_or("127.0.0.1:3413").parse()?,
|
||||||
|
grin_node_secret_path: match grin_node_secret_path {
|
||||||
|
Some(p) => Some(p.to_owned()),
|
||||||
|
None => config::node_secret_path().to_str().map(|p| p.to_owned()),
|
||||||
|
},
|
||||||
wallet_owner_url: wallet_owner_url.unwrap_or("127.0.0.1:3420").parse()?,
|
wallet_owner_url: wallet_owner_url.unwrap_or("127.0.0.1:3420").parse()?,
|
||||||
|
wallet_owner_secret_path: match wallet_owner_secret_path {
|
||||||
|
Some(p) => Some(p.to_owned()),
|
||||||
|
None => config::wallet_owner_secret_path()
|
||||||
|
.to_str()
|
||||||
|
.map(|p| p.to_owned()),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let password = prompt_password_confirm();
|
let password = prompt_password_confirm();
|
||||||
|
@ -93,31 +102,41 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
server_config.grin_node_url = grin_node_url.parse()?;
|
server_config.grin_node_url = grin_node_url.parse()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override grin_node_secret_path, if supplied
|
||||||
|
if let Some(grin_node_secret_path) = grin_node_secret_path {
|
||||||
|
server_config.grin_node_secret_path = Some(grin_node_secret_path.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
// Override wallet_owner_url, if supplied
|
// Override wallet_owner_url, if supplied
|
||||||
if let Some(wallet_owner_url) = wallet_owner_url {
|
if let Some(wallet_owner_url) = wallet_owner_url {
|
||||||
server_config.wallet_owner_url = wallet_owner_url.parse()?;
|
server_config.wallet_owner_url = wallet_owner_url.parse()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override wallet_owner_secret_path, if supplied
|
||||||
|
if let Some(wallet_owner_secret_path) = wallet_owner_secret_path {
|
||||||
|
server_config.wallet_owner_secret_path = Some(wallet_owner_secret_path.to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
// Open wallet
|
// Open wallet
|
||||||
let wallet_pass = prompt_wallet_password(&args.value_of("wallet_pass"));
|
let wallet_pass = prompt_wallet_password(&args.value_of("wallet_pass"));
|
||||||
let wallet = HttpWallet::open_wallet(&server_config.wallet_owner_url, &wallet_pass)?;
|
let wallet = HttpWallet::open_wallet(
|
||||||
|
&server_config.wallet_owner_url,
|
||||||
|
&server_config.wallet_owner_api_secret(),
|
||||||
|
&wallet_pass,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Create GrinNode
|
// Create GrinNode
|
||||||
let node = HttpGrinNode::new(&server_config.grin_node_url, &None);
|
let node = HttpGrinNode::new(
|
||||||
|
&server_config.grin_node_url,
|
||||||
|
&server_config.node_api_secret(),
|
||||||
|
);
|
||||||
|
|
||||||
let stop_state = Arc::new(StopState::new());
|
let stop_state = Arc::new(StopState::new());
|
||||||
|
|
||||||
let stop_state_clone = stop_state.clone();
|
let stop_state_clone = stop_state.clone();
|
||||||
|
|
||||||
let rt = Runtime::new()?;
|
let rt = Runtime::new()?;
|
||||||
rt.spawn(async move {
|
rt.spawn(async move {
|
||||||
let shutdown_signal = async move {
|
futures::executor::block_on(build_signals_fut());
|
||||||
// Wait for the CTRL+C signal
|
|
||||||
tokio::signal::ctrl_c()
|
|
||||||
.await
|
|
||||||
.expect("failed to install CTRL+C signal handler");
|
|
||||||
};
|
|
||||||
futures::executor::block_on(shutdown_signal);
|
|
||||||
stop_state_clone.stop();
|
stop_state_clone.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -130,6 +149,30 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn build_signals_fut() {
|
||||||
|
if cfg!(unix) {
|
||||||
|
use tokio::signal::unix::{signal, SignalKind};
|
||||||
|
|
||||||
|
// Listen for SIGINT, SIGQUIT, and SIGTERM
|
||||||
|
let mut terminate_signal =
|
||||||
|
signal(SignalKind::terminate()).expect("failed to create terminate signal");
|
||||||
|
let mut quit_signal = signal(SignalKind::quit()).expect("failed to create quit signal");
|
||||||
|
let mut interrupt_signal =
|
||||||
|
signal(SignalKind::interrupt()).expect("failed to create interrupt signal");
|
||||||
|
|
||||||
|
futures::future::select_all(vec![
|
||||||
|
Box::pin(terminate_signal.recv()),
|
||||||
|
Box::pin(quit_signal.recv()),
|
||||||
|
Box::pin(interrupt_signal.recv()),
|
||||||
|
])
|
||||||
|
.await;
|
||||||
|
} else {
|
||||||
|
tokio::signal::ctrl_c()
|
||||||
|
.await
|
||||||
|
.expect("failed to install CTRL+C signal handler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn prompt_password() -> ZeroingString {
|
fn prompt_password() -> ZeroingString {
|
||||||
ZeroingString::from(rpassword::prompt_password_stdout("Server password: ").unwrap())
|
ZeroingString::from(rpassword::prompt_password_stdout("Server password: ").unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,15 +116,14 @@ pub mod comsig_serde {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ComSignature from a hex string
|
/// Creates a ComSignature from a hex string
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> std::result::Result<ComSignature, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<ComSignature, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
let bytes = String::deserialize(deserializer)
|
let bytes = String::deserialize(deserializer)
|
||||||
.and_then(|string| grin_util::from_hex(&string).map_err(Error::custom))?;
|
.and_then(|string| grin_util::from_hex(&string).map_err(Error::custom))?;
|
||||||
let sig: ComSignature =
|
let sig: ComSignature = ser::deserialize_default(&mut &bytes[..]).map_err(Error::custom)?;
|
||||||
grin_core::ser::deserialize_default(&mut &bytes[..]).map_err(Error::custom)?;
|
|
||||||
Ok(sig)
|
Ok(sig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,9 @@ mod tests {
|
||||||
interval_s: 1,
|
interval_s: 1,
|
||||||
addr: TcpListener::bind("127.0.0.1:0")?.local_addr()?,
|
addr: TcpListener::bind("127.0.0.1:0")?.local_addr()?,
|
||||||
grin_node_url: "127.0.0.1:3413".parse()?,
|
grin_node_url: "127.0.0.1:3413".parse()?,
|
||||||
|
grin_node_secret_path: None,
|
||||||
wallet_owner_url: "127.0.0.1:3420".parse()?,
|
wallet_owner_url: "127.0.0.1:3420".parse()?,
|
||||||
|
wallet_owner_secret_path: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let threaded_rt = runtime::Runtime::new()?;
|
let threaded_rt = runtime::Runtime::new()?;
|
||||||
|
|
|
@ -85,6 +85,7 @@ pub fn assemble_tx(
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HttpWallet {
|
pub struct HttpWallet {
|
||||||
wallet_owner_url: SocketAddr,
|
wallet_owner_url: SocketAddr,
|
||||||
|
wallet_owner_secret: Option<String>,
|
||||||
shared_key: SecretKey,
|
shared_key: SecretKey,
|
||||||
token: Token,
|
token: Token,
|
||||||
}
|
}
|
||||||
|
@ -104,6 +105,7 @@ impl HttpWallet {
|
||||||
/// Calls the 'open_wallet' using the RPC API.
|
/// Calls the 'open_wallet' using the RPC API.
|
||||||
pub fn open_wallet(
|
pub fn open_wallet(
|
||||||
wallet_owner_url: &SocketAddr,
|
wallet_owner_url: &SocketAddr,
|
||||||
|
wallet_owner_secret: &Option<String>,
|
||||||
wallet_pass: &ZeroingString,
|
wallet_pass: &ZeroingString,
|
||||||
) -> Result<HttpWallet> {
|
) -> Result<HttpWallet> {
|
||||||
println!("Opening wallet at {}", wallet_owner_url);
|
println!("Opening wallet at {}", wallet_owner_url);
|
||||||
|
@ -115,6 +117,7 @@ impl HttpWallet {
|
||||||
});
|
});
|
||||||
let token: Token = HttpWallet::send_enc_request(
|
let token: Token = HttpWallet::send_enc_request(
|
||||||
&wallet_owner_url,
|
&wallet_owner_url,
|
||||||
|
&wallet_owner_secret,
|
||||||
"open_wallet",
|
"open_wallet",
|
||||||
&open_wallet_params,
|
&open_wallet_params,
|
||||||
&shared_key,
|
&shared_key,
|
||||||
|
@ -123,6 +126,7 @@ impl HttpWallet {
|
||||||
|
|
||||||
Ok(HttpWallet {
|
Ok(HttpWallet {
|
||||||
wallet_owner_url: wallet_owner_url.clone(),
|
wallet_owner_url: wallet_owner_url.clone(),
|
||||||
|
wallet_owner_secret: wallet_owner_secret.clone(),
|
||||||
shared_key: shared_key.clone(),
|
shared_key: shared_key.clone(),
|
||||||
token: token.clone(),
|
token: token.clone(),
|
||||||
})
|
})
|
||||||
|
@ -152,6 +156,7 @@ impl HttpWallet {
|
||||||
|
|
||||||
fn send_enc_request<D: serde::de::DeserializeOwned>(
|
fn send_enc_request<D: serde::de::DeserializeOwned>(
|
||||||
wallet_owner_url: &SocketAddr,
|
wallet_owner_url: &SocketAddr,
|
||||||
|
wallet_owner_secret: &Option<String>,
|
||||||
method: &str,
|
method: &str,
|
||||||
params: &serde_json::Value,
|
params: &serde_json::Value,
|
||||||
shared_key: &SecretKey,
|
shared_key: &SecretKey,
|
||||||
|
@ -164,8 +169,11 @@ impl HttpWallet {
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
});
|
});
|
||||||
let enc_req = EncryptedRequest::from_json(&JsonId::IntId(1), &req, &shared_key)?;
|
let enc_req = EncryptedRequest::from_json(&JsonId::IntId(1), &req, &shared_key)?;
|
||||||
let res =
|
let res = client::post::<EncryptedRequest, EncryptedResponse>(
|
||||||
client::post::<EncryptedRequest, EncryptedResponse>(url.as_str(), None, &enc_req)?;
|
url.as_str(),
|
||||||
|
wallet_owner_secret.clone(),
|
||||||
|
&enc_req,
|
||||||
|
)?;
|
||||||
let decrypted = res.decrypt(&shared_key)?;
|
let decrypted = res.decrypt(&shared_key)?;
|
||||||
let response: Response = serde_json::from_value(decrypted.clone())?;
|
let response: Response = serde_json::from_value(decrypted.clone())?;
|
||||||
let parsed = serde_json::from_value(response.result.unwrap().get("Ok").unwrap().clone())?;
|
let parsed = serde_json::from_value(response.result.unwrap().get("Ok").unwrap().clone())?;
|
||||||
|
@ -205,6 +213,7 @@ impl Wallet for HttpWallet {
|
||||||
});
|
});
|
||||||
let output: OutputWithBlind = HttpWallet::send_enc_request(
|
let output: OutputWithBlind = HttpWallet::send_enc_request(
|
||||||
&self.wallet_owner_url,
|
&self.wallet_owner_url,
|
||||||
|
&self.wallet_owner_secret,
|
||||||
"build_output",
|
"build_output",
|
||||||
&req_json,
|
&req_json,
|
||||||
&self.shared_key,
|
&self.shared_key,
|
||||||
|
|
Loading…
Reference in a new issue