migrate to v2
- lots to check and do
This commit is contained in:
Generated
+2024
-724
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@
|
||||
"webpack:prod": "yarn webpack --progress --config webpack.prod.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/helper-simple-access": "^7.25.9",
|
||||
"@emotion/react": "^11.7.0",
|
||||
"@emotion/styled": "^11.6.0",
|
||||
"@hookform/resolvers": "^2.8.0",
|
||||
@@ -33,7 +34,10 @@
|
||||
"@nymproject/react": "^1.0.0",
|
||||
"@nymproject/types": "^1.0.0",
|
||||
"@storybook/react": "^6.5.15",
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"@tauri-apps/api": "^2.4.0",
|
||||
"@tauri-apps/cli": "^2.4.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.2.2",
|
||||
"@tauri-apps/plugin-updater": "^2.0.0",
|
||||
"@tauri-apps/tauri-forage": "^1.0.0-beta.2",
|
||||
"big.js": "^6.2.1",
|
||||
"bs58": "^4.0.1",
|
||||
@@ -67,7 +71,7 @@
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
|
||||
"@storybook/react": "^6.5.15",
|
||||
"@svgr/webpack": "^6.1.1",
|
||||
"@tauri-apps/cli": "^1.0.5",
|
||||
"@tauri-apps/cli": "^2.4.0",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^12.0.0",
|
||||
"@types/big.js": "^6.1.6",
|
||||
@@ -125,4 +129,4 @@
|
||||
"webpack-merge": "^5.8.0"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,17 @@ rust-version = "1.76"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "=1.2.1", features = [] }
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
tauri-codegen = "=1.2.1"
|
||||
tauri-macros = "=1.2.1"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.68"
|
||||
tauri-plugin-updater = "2"
|
||||
tauri-plugin-clipboard-manager = "2"
|
||||
tauri-plugin-shell = "2"
|
||||
tauri-plugin-process = "2"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize", "rand"] }
|
||||
cfg-if = "1.0.0"
|
||||
colored = "2.0"
|
||||
@@ -38,7 +42,7 @@ serde_json = "1.0"
|
||||
serde_repr = "0.1"
|
||||
strum = { version = "0.23", features = ["derive"] }
|
||||
tap = "1"
|
||||
tauri = { version = "=1.2.3", features = ["clipboard-all", "shell-open", "updater", "window-maximize", "window-print"] }
|
||||
tauri = { version = "2", features = [] }
|
||||
#tendermint-rpc = "0.23.0"
|
||||
time = { version = "0.3.30", features = ["local-offset"] }
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"identifier": "migrated",
|
||||
"description": "permissions that were migrated from v1",
|
||||
"local": true,
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default"]}}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ use nym_validator_client::nyxd::AccountId as CosmosAccountId;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::IntoEnumIterator;
|
||||
use tauri::Manager;
|
||||
use url::Url;
|
||||
|
||||
use nym_config::defaults::{DenomDetailsOwned, NymNetworkDetails, ValidatorDetails};
|
||||
@@ -104,32 +105,35 @@ impl NetworkConfig {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn root_directory() -> PathBuf {
|
||||
tauri::api::path::config_dir().expect("Failed to get config directory")
|
||||
fn root_directory(app_handle: &tauri::AppHandle) -> PathBuf {
|
||||
app_handle
|
||||
.path()
|
||||
.local_data_dir()
|
||||
.expect("Failed to get config directory")
|
||||
}
|
||||
|
||||
fn config_directory() -> PathBuf {
|
||||
Self::root_directory().join(CONFIG_DIR_NAME)
|
||||
fn config_directory(app_handle: &tauri::AppHandle) -> PathBuf {
|
||||
Self::root_directory(app_handle).join(CONFIG_DIR_NAME)
|
||||
}
|
||||
|
||||
fn config_file_path(network: Option<WalletNetwork>) -> PathBuf {
|
||||
fn config_file_path(app_handle: &tauri::AppHandle, network: Option<WalletNetwork>) -> PathBuf {
|
||||
if let Some(network) = network {
|
||||
let network_filename = format!("{}.toml", network.as_key());
|
||||
Self::config_directory().join(network_filename)
|
||||
Self::config_directory(app_handle).join(network_filename)
|
||||
} else {
|
||||
Self::config_directory().join(CONFIG_FILENAME)
|
||||
Self::config_directory(app_handle).join(CONFIG_FILENAME)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_to_files(&self) -> io::Result<()> {
|
||||
pub fn save_to_files(&self, app_handle: &tauri::AppHandle) -> io::Result<()> {
|
||||
log::trace!("Config::save_to_file");
|
||||
|
||||
// Make sure the whole directory structure actually exists
|
||||
fs::create_dir_all(Self::config_directory())?;
|
||||
fs::create_dir_all(Self::config_directory(app_handle))?;
|
||||
|
||||
// Global config
|
||||
if let Some(global) = &self.global {
|
||||
let location = Self::config_file_path(None);
|
||||
let location = Self::config_file_path(app_handle, None);
|
||||
|
||||
match toml::to_string_pretty(&global)
|
||||
.map_err(|toml_err| io::Error::new(io::ErrorKind::Other, toml_err))
|
||||
@@ -150,7 +154,7 @@ impl Config {
|
||||
}
|
||||
};
|
||||
|
||||
let location = Self::config_file_path(Some(network));
|
||||
let location = Self::config_file_path(app_handle, Some(network));
|
||||
match toml::to_string_pretty(config)
|
||||
.map_err(|toml_err| io::Error::new(io::ErrorKind::Other, toml_err))
|
||||
.map(|toml| fs::write(location.clone(), toml))
|
||||
@@ -162,10 +166,10 @@ impl Config {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_from_files() -> Self {
|
||||
pub fn load_from_files(app_handle: &tauri::AppHandle) -> Self {
|
||||
// Global
|
||||
let global = {
|
||||
let file = Self::config_file_path(None);
|
||||
let file = Self::config_file_path(app_handle, None);
|
||||
match load_from_file::<GlobalConfig>(file.clone()) {
|
||||
Ok(global) => {
|
||||
log::debug!("Loaded from file {:#?}", file);
|
||||
@@ -181,7 +185,7 @@ impl Config {
|
||||
// One file per network
|
||||
let mut networks = HashMap::new();
|
||||
for network in WalletNetwork::iter() {
|
||||
let file = Self::config_file_path(Some(network));
|
||||
let file = Self::config_file_path(app_handle, Some(network));
|
||||
match load_from_file::<NetworkConfig>(file.clone()) {
|
||||
Ok(config) => {
|
||||
log::trace!("Loaded from file {:#?}", file);
|
||||
@@ -261,6 +265,8 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
////////
|
||||
|
||||
pub fn select_nyxd_url(&mut self, nyxd_url: Url, network: WalletNetwork) {
|
||||
if let Some(net) = self.networks.get_mut(&network.as_key()) {
|
||||
net.selected_nyxd_url = Some(nyxd_url);
|
||||
@@ -531,145 +537,145 @@ impl From<NymNetworkDetails> for NetworkDetails {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
|
||||
fn test_config() -> Config {
|
||||
let netconfig = NetworkConfig {
|
||||
selected_nyxd_url: None,
|
||||
selected_api_url: Some("https://my_api_url.com".parse().unwrap()),
|
||||
// fn test_config() -> Config {
|
||||
// let netconfig = NetworkConfig {
|
||||
// selected_nyxd_url: None,
|
||||
// selected_api_url: Some("https://my_api_url.com".parse().unwrap()),
|
||||
|
||||
nyxd_urls: Some(vec![
|
||||
ValidatorConfigEntry {
|
||||
nyxd_url: "https://foo".parse().unwrap(),
|
||||
nyxd_name: Some("FooName".to_string()),
|
||||
api_url: None,
|
||||
},
|
||||
ValidatorConfigEntry {
|
||||
nyxd_url: "https://bar".parse().unwrap(),
|
||||
nyxd_name: None,
|
||||
api_url: Some("https://bar/api".parse().unwrap()),
|
||||
},
|
||||
ValidatorConfigEntry {
|
||||
nyxd_url: "https://baz".parse().unwrap(),
|
||||
nyxd_name: None,
|
||||
api_url: Some("https://baz/api".parse().unwrap()),
|
||||
},
|
||||
]),
|
||||
..NetworkConfig::default()
|
||||
};
|
||||
// nyxd_urls: Some(vec![
|
||||
// ValidatorConfigEntry {
|
||||
// nyxd_url: "https://foo".parse().unwrap(),
|
||||
// nyxd_name: Some("FooName".to_string()),
|
||||
// api_url: None,
|
||||
// },
|
||||
// ValidatorConfigEntry {
|
||||
// nyxd_url: "https://bar".parse().unwrap(),
|
||||
// nyxd_name: None,
|
||||
// api_url: Some("https://bar/api".parse().unwrap()),
|
||||
// },
|
||||
// ValidatorConfigEntry {
|
||||
// nyxd_url: "https://baz".parse().unwrap(),
|
||||
// nyxd_name: None,
|
||||
// api_url: Some("https://baz/api".parse().unwrap()),
|
||||
// },
|
||||
// ]),
|
||||
// ..NetworkConfig::default()
|
||||
// };
|
||||
|
||||
Config {
|
||||
base: Base::default(),
|
||||
global: Some(GlobalConfig::default()),
|
||||
networks: [(WalletNetwork::MAINNET.as_key(), netconfig)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
// Config {
|
||||
// base: Base::default(),
|
||||
// global: Some(GlobalConfig::default()),
|
||||
// networks: [(WalletNetwork::MAINNET.as_key(), netconfig)]
|
||||
// .into_iter()
|
||||
// .collect(),
|
||||
// }
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn serialize_to_toml() {
|
||||
let config = test_config();
|
||||
let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
assert_eq!(
|
||||
toml::to_string_pretty(netconfig).unwrap(),
|
||||
r#"version = 1
|
||||
selected_api_url = 'https://my_api_url.com/'
|
||||
// #[test]
|
||||
// fn serialize_to_toml() {
|
||||
// let config = test_config();
|
||||
// let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
// assert_eq!(
|
||||
// toml::to_string_pretty(netconfig).unwrap(),
|
||||
// r#"version = 1
|
||||
// selected_api_url = 'https://my_api_url.com/'
|
||||
|
||||
[[nyxd_urls]]
|
||||
nyxd_url = 'https://foo/'
|
||||
nyxd_name = 'FooName'
|
||||
// [[nyxd_urls]]
|
||||
// nyxd_url = 'https://foo/'
|
||||
// nyxd_name = 'FooName'
|
||||
|
||||
[[nyxd_urls]]
|
||||
nyxd_url = 'https://bar/'
|
||||
api_url = 'https://bar/api'
|
||||
// [[nyxd_urls]]
|
||||
// nyxd_url = 'https://bar/'
|
||||
// api_url = 'https://bar/api'
|
||||
|
||||
[[nyxd_urls]]
|
||||
nyxd_url = 'https://baz/'
|
||||
api_url = 'https://baz/api'
|
||||
"#
|
||||
);
|
||||
}
|
||||
// [[nyxd_urls]]
|
||||
// nyxd_url = 'https://baz/'
|
||||
// api_url = 'https://baz/api'
|
||||
// "#
|
||||
// );
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn serialize_to_json() {
|
||||
let config = test_config();
|
||||
let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
println!("{}", serde_json::to_string_pretty(netconfig).unwrap());
|
||||
assert_eq!(
|
||||
serde_json::to_string_pretty(netconfig).unwrap(),
|
||||
r#"{
|
||||
"version": 1,
|
||||
"selected_nyxd_url": null,
|
||||
"default_nyxd_url": null,
|
||||
"selected_api_url": "https://my_api_url.com/",
|
||||
"nyxd_urls": [
|
||||
{
|
||||
"nyxd_url": "https://foo/",
|
||||
"nyxd_name": "FooName",
|
||||
"api_url": null
|
||||
},
|
||||
{
|
||||
"nyxd_url": "https://bar/",
|
||||
"nyxd_name": null,
|
||||
"api_url": "https://bar/api"
|
||||
},
|
||||
{
|
||||
"nyxd_url": "https://baz/",
|
||||
"nyxd_name": null,
|
||||
"api_url": "https://baz/api"
|
||||
}
|
||||
]
|
||||
}"#
|
||||
);
|
||||
}
|
||||
// #[test]
|
||||
// fn serialize_to_json() {
|
||||
// let config = test_config();
|
||||
// let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
// println!("{}", serde_json::to_string_pretty(netconfig).unwrap());
|
||||
// assert_eq!(
|
||||
// serde_json::to_string_pretty(netconfig).unwrap(),
|
||||
// r#"{
|
||||
// "version": 1,
|
||||
// "selected_nyxd_url": null,
|
||||
// "default_nyxd_url": null,
|
||||
// "selected_api_url": "https://my_api_url.com/",
|
||||
// "nyxd_urls": [
|
||||
// {
|
||||
// "nyxd_url": "https://foo/",
|
||||
// "nyxd_name": "FooName",
|
||||
// "api_url": null
|
||||
// },
|
||||
// {
|
||||
// "nyxd_url": "https://bar/",
|
||||
// "nyxd_name": null,
|
||||
// "api_url": "https://bar/api"
|
||||
// },
|
||||
// {
|
||||
// "nyxd_url": "https://baz/",
|
||||
// "nyxd_name": null,
|
||||
// "api_url": "https://baz/api"
|
||||
// }
|
||||
// ]
|
||||
// }"#
|
||||
// );
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn serialize_and_deserialize_to_toml() {
|
||||
let config = test_config();
|
||||
let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
let config_str = toml::to_string_pretty(netconfig).unwrap();
|
||||
let config_from_toml: NetworkConfig = toml::from_str(&config_str).unwrap();
|
||||
assert_eq!(netconfig, &config_from_toml);
|
||||
}
|
||||
// #[test]
|
||||
// fn serialize_and_deserialize_to_toml() {
|
||||
// let config = test_config();
|
||||
// let netconfig = &config.networks[&WalletNetwork::MAINNET.as_key()];
|
||||
// let config_str = toml::to_string_pretty(netconfig).unwrap();
|
||||
// let config_from_toml: NetworkConfig = toml::from_str(&config_str).unwrap();
|
||||
// assert_eq!(netconfig, &config_from_toml);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn get_urls_parsed_from_config() {
|
||||
let config = test_config();
|
||||
// #[test]
|
||||
// fn get_urls_parsed_from_config() {
|
||||
// let config = test_config();
|
||||
|
||||
let nyxd_url = config
|
||||
.get_configured_validators(WalletNetwork::MAINNET)
|
||||
.next()
|
||||
.map(|v| v.nyxd_url)
|
||||
.unwrap();
|
||||
assert_eq!(nyxd_url.as_ref(), "https://foo/");
|
||||
// let nyxd_url = config
|
||||
// .get_configured_validators(WalletNetwork::MAINNET)
|
||||
// .next()
|
||||
// .map(|v| v.nyxd_url)
|
||||
// .unwrap();
|
||||
// assert_eq!(nyxd_url.as_ref(), "https://foo/");
|
||||
|
||||
// The first entry is missing an API URL
|
||||
let api_url = config
|
||||
.get_configured_validators(WalletNetwork::MAINNET)
|
||||
.next()
|
||||
.and_then(|v| v.api_url);
|
||||
assert_eq!(api_url, None);
|
||||
}
|
||||
// // The first entry is missing an API URL
|
||||
// let api_url = config
|
||||
// .get_configured_validators(WalletNetwork::MAINNET)
|
||||
// .next()
|
||||
// .and_then(|v| v.api_url);
|
||||
// assert_eq!(api_url, None);
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn get_urls_from_defaults() {
|
||||
let config = Config::default();
|
||||
// #[test]
|
||||
// fn get_urls_from_defaults() {
|
||||
// let config = Config::default();
|
||||
|
||||
let nyxd_url = config
|
||||
.get_base_validators(WalletNetwork::MAINNET)
|
||||
.next()
|
||||
.map(|v| v.nyxd_url)
|
||||
.unwrap();
|
||||
assert_eq!(nyxd_url.as_ref(), "https://rpc.nymtech.net/");
|
||||
// let nyxd_url = config
|
||||
// .get_base_validators(WalletNetwork::MAINNET)
|
||||
// .next()
|
||||
// .map(|v| v.nyxd_url)
|
||||
// .unwrap();
|
||||
// assert_eq!(nyxd_url.as_ref(), "https://rpc.nymtech.net/");
|
||||
|
||||
let api_url = config
|
||||
.get_base_validators(WalletNetwork::MAINNET)
|
||||
.next()
|
||||
.and_then(|v| v.api_url)
|
||||
.unwrap();
|
||||
assert_eq!(api_url.as_ref(), "https://validator.nymtech.net/api/",);
|
||||
}
|
||||
}
|
||||
// let api_url = config
|
||||
// .get_base_validators(WalletNetwork::MAINNET)
|
||||
// .next()
|
||||
// .and_then(|v| v.api_url)
|
||||
// .unwrap();
|
||||
// assert_eq!(api_url.as_ref(), "https://validator.nymtech.net/api/",);
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::str::FromStr;
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
use serde::Serialize;
|
||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||
use tauri::Manager;
|
||||
use tauri::Emitter;
|
||||
use time::{format_description, OffsetDateTime};
|
||||
|
||||
fn formatted_time() -> String {
|
||||
@@ -61,7 +61,7 @@ pub fn setup_logging(app_handle: tauri::AppHandle) -> Result<(), log::SetLoggerE
|
||||
message: record.args().to_string(),
|
||||
level: record.level().into(),
|
||||
};
|
||||
app_handle.emit_all("log://log", msg).unwrap();
|
||||
app_handle.emit("log://log", msg).unwrap();
|
||||
}));
|
||||
|
||||
base_config
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
windows_subsystem = "windows"
|
||||
)]
|
||||
|
||||
use tauri::{Manager, Menu};
|
||||
|
||||
use nym_mixnet_contract_common::{Gateway, MixNode};
|
||||
use tauri::menu::{MenuBuilder, MenuItemBuilder, SubmenuBuilder};
|
||||
use tauri::Manager;
|
||||
|
||||
use crate::menu::AddDefaultSubmenus;
|
||||
use crate::menu::SHOW_LOG_WINDOW;
|
||||
use crate::operations::app;
|
||||
use crate::operations::help;
|
||||
use crate::operations::mixnet;
|
||||
@@ -210,13 +210,31 @@ fn main() {
|
||||
app::react::set_react_state,
|
||||
app::react::get_react_state,
|
||||
])
|
||||
.menu(Menu::os_default(&context.package_info().name).add_default_app_submenus())
|
||||
.on_menu_event(|event| {
|
||||
if event.menu_item_id() == menu::SHOW_LOG_WINDOW {
|
||||
let _r = help::log::help_log_toggle_window(event.window().app_handle());
|
||||
.menu(|app| {
|
||||
// Create a menu builder
|
||||
let menu_builder = MenuBuilder::new(app);
|
||||
if ::std::env::var("NYM_WALLET_ENABLE_LOG").is_ok() {
|
||||
let help_text = MenuItemBuilder::with_id(SHOW_LOG_WINDOW, "Show logs")
|
||||
.build(app)
|
||||
.expect("Failed to create menu item");
|
||||
|
||||
let submenu = SubmenuBuilder::new(app, "Help")
|
||||
.items(&[&help_text])
|
||||
.build()
|
||||
.expect("Failed to create help submenu");
|
||||
|
||||
menu_builder.item(&submenu).build()
|
||||
} else {
|
||||
// Build a default menu without the submenu
|
||||
menu_builder.build()
|
||||
}
|
||||
})
|
||||
.setup(|app| Ok(log::setup_logging(app.app_handle())?))
|
||||
.on_menu_event(|app, event| {
|
||||
if event.id() == SHOW_LOG_WINDOW {
|
||||
let _r = help::log::help_log_toggle_window(app.app_handle().clone());
|
||||
}
|
||||
})
|
||||
.setup(|app| Ok(log::setup_logging(app.app_handle().clone())?))
|
||||
.run(context)
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use tauri::Menu;
|
||||
use tauri::{CustomMenuItem, Submenu};
|
||||
use tauri::menu::Menu;
|
||||
use tauri::menu::{MenuBuilder, MenuItemBuilder, SubmenuBuilder};
|
||||
|
||||
pub const SHOW_LOG_WINDOW: &str = "show_log_window";
|
||||
|
||||
@@ -7,16 +7,29 @@ pub trait AddDefaultSubmenus {
|
||||
fn add_default_app_submenus(self) -> Self;
|
||||
}
|
||||
|
||||
impl AddDefaultSubmenus for Menu {
|
||||
impl<R: tauri::Runtime> AddDefaultSubmenus for Menu<R> {
|
||||
#[allow(dead_code)]
|
||||
fn add_default_app_submenus(self) -> Self {
|
||||
if ::std::env::var("NYM_WALLET_ENABLE_LOG").is_ok() {
|
||||
let submenu = Submenu::new(
|
||||
"Help",
|
||||
Menu::new().add_item(CustomMenuItem::new(SHOW_LOG_WINDOW, "Show logs")),
|
||||
);
|
||||
return self.add_submenu(submenu);
|
||||
let app_handle = self.app_handle();
|
||||
|
||||
let help_text = MenuItemBuilder::with_id(SHOW_LOG_WINDOW, "Show logs")
|
||||
.build(app_handle)
|
||||
.expect("Failed to create menu item");
|
||||
|
||||
let submenu = SubmenuBuilder::new(app_handle, "Help")
|
||||
.items(&[&help_text])
|
||||
.build()
|
||||
.expect("Failed to create help submenu");
|
||||
|
||||
let menu_builder = MenuBuilder::new(app_handle);
|
||||
|
||||
match menu_builder.item(&submenu).build() {
|
||||
Ok(new_menu) => new_menu,
|
||||
Err(_) => self,
|
||||
}
|
||||
} else {
|
||||
self
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,27 +3,46 @@
|
||||
|
||||
use crate::error::BackendError;
|
||||
use nym_wallet_types::app::AppVersion;
|
||||
use tauri_plugin_updater::UpdaterExt;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn check_version(handle: tauri::AppHandle) -> Result<AppVersion, BackendError> {
|
||||
log::info!(">>> Getting app version info");
|
||||
let res = tauri::updater::builder(handle)
|
||||
.check()
|
||||
.await
|
||||
.map(|u| AppVersion {
|
||||
current_version: u.current_version().to_string(),
|
||||
latest_version: u.latest_version().to_owned(),
|
||||
is_update_available: u.is_update_available(),
|
||||
|
||||
let updater = handle.updater().map_err(|e| {
|
||||
log::error!("Failed to get updater: {}", e);
|
||||
BackendError::CheckAppVersionError
|
||||
})?;
|
||||
|
||||
// Then check for updates
|
||||
let update_info = updater.check().await.map_err(|e| {
|
||||
log::error!("An error occurred while checking for app update {}", e);
|
||||
BackendError::CheckAppVersionError
|
||||
})?;
|
||||
|
||||
// Process the result
|
||||
if let Some(update) = update_info {
|
||||
log::debug!(
|
||||
"<<< update available: [true], current version {}, latest version {}",
|
||||
update.current_version,
|
||||
update.version
|
||||
);
|
||||
Ok(AppVersion {
|
||||
current_version: update.current_version.to_string(),
|
||||
latest_version: update.version,
|
||||
is_update_available: true,
|
||||
})
|
||||
.map_err(|e| {
|
||||
log::error!("An error ocurred while checking for app update {}", e);
|
||||
BackendError::CheckAppVersionError
|
||||
})?;
|
||||
log::debug!(
|
||||
"<<< update available: [{}], current version {}, latest version {}",
|
||||
res.is_update_available,
|
||||
res.current_version,
|
||||
res.latest_version
|
||||
);
|
||||
Ok(res)
|
||||
} else {
|
||||
// No update available
|
||||
let current_version = handle.package_info().version.to_string();
|
||||
log::debug!(
|
||||
"<<< update available: [false], current version {}",
|
||||
current_version
|
||||
);
|
||||
Ok(AppVersion {
|
||||
current_version: current_version.clone(),
|
||||
latest_version: current_version,
|
||||
is_update_available: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ async fn create_window(
|
||||
) -> Result<(), BackendError> {
|
||||
// create the new window first, to stop the app process from exiting
|
||||
log::info!("Creating {} window...", new_window_label);
|
||||
match tauri::WindowBuilder::new(
|
||||
match tauri::WebviewWindowBuilder::new(
|
||||
&app_handle,
|
||||
new_window_label,
|
||||
tauri::WindowUrl::App(new_window_url.into()),
|
||||
"main",
|
||||
tauri::WebviewUrl::App(new_window_url.into()),
|
||||
)
|
||||
.title("Nym Wallet")
|
||||
.build()
|
||||
@@ -49,7 +49,7 @@ async fn create_window(
|
||||
}
|
||||
|
||||
// close the old window
|
||||
match app_handle.windows().get(try_close_window_label) {
|
||||
match app_handle.get_webview_window(try_close_window_label) {
|
||||
Some(try_close_window) => {
|
||||
if let Err(err) = try_close_window.close() {
|
||||
log::error!("Could not close window: {err}")
|
||||
|
||||
@@ -3,7 +3,7 @@ use tauri::Manager;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn help_log_toggle_window(app_handle: tauri::AppHandle) -> Result<(), BackendError> {
|
||||
if let Some(current_log_window) = app_handle.windows().get("log") {
|
||||
if let Some(current_log_window) = app_handle.get_webview_window("log") {
|
||||
log::info!("Closing log window...");
|
||||
if let Err(err) = current_log_window.close() {
|
||||
log::error!("Unable to close log window: {err}");
|
||||
@@ -12,9 +12,13 @@ pub fn help_log_toggle_window(app_handle: tauri::AppHandle) -> Result<(), Backen
|
||||
}
|
||||
|
||||
log::info!("Creating log window...");
|
||||
match tauri::WindowBuilder::new(&app_handle, "log", tauri::WindowUrl::App("log.html".into()))
|
||||
.title("Nym Wallet Logs")
|
||||
.build()
|
||||
match tauri::WebviewWindowBuilder::new(
|
||||
&app_handle,
|
||||
"log",
|
||||
tauri::WebviewUrl::App("log.html".into()),
|
||||
)
|
||||
.title("Nym Wallet Logs")
|
||||
.build()
|
||||
{
|
||||
Ok(window) => {
|
||||
if let Err(err) = window.set_focus() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,78 +1,69 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-wallet",
|
||||
"version": "1.2.15"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
"devPath": "http://localhost:9000",
|
||||
"beforeDevCommand": "",
|
||||
"beforeBuildCommand": ""
|
||||
},
|
||||
"tauri": {
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "net.nymtech.wallet",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Copyright © 2021-2023 Nym Technologies SA",
|
||||
"category": "Business",
|
||||
"shortDescription": "Nym desktop wallet allows you to manage your NYM tokens",
|
||||
"longDescription": "",
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"windows": {
|
||||
"certificateThumbprint": "6DB77B1F529A0804FE0E6843A3EB8A8CECFFD408",
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": "http://timestamp.comodoca.com"
|
||||
},
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Copyright © 2021-2025 Nym Technologies SA",
|
||||
"category": "Business",
|
||||
"shortDescription": "Nym desktop wallet allows you to manage your NYM tokens",
|
||||
"longDescription": "",
|
||||
"macOS": {
|
||||
"frameworks": [],
|
||||
"minimumSystemVersion": "",
|
||||
"exceptionDomain": "",
|
||||
"signingIdentity": "Developer ID Application: Nym Technologies SA (VW5DZLFHM5)",
|
||||
"entitlements": null
|
||||
},
|
||||
"linux": {
|
||||
"deb": {
|
||||
"depends": []
|
||||
},
|
||||
"macOS": {
|
||||
"frameworks": [],
|
||||
"minimumSystemVersion": "",
|
||||
"exceptionDomain": "",
|
||||
"signingIdentity": "Developer ID Application: Nym Technologies SA (VW5DZLFHM5)",
|
||||
"entitlements": null
|
||||
},
|
||||
"windows": {
|
||||
"certificateThumbprint": "6DB77B1F529A0804FE0E6843A3EB8A8CECFFD408",
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": "http://timestamp.comodoca.com"
|
||||
}
|
||||
},
|
||||
"createUpdaterArtifacts": "v1Compatible"
|
||||
},
|
||||
"build": {
|
||||
"beforeBuildCommand": "",
|
||||
"frontendDist": "../dist",
|
||||
"beforeDevCommand": "",
|
||||
"devUrl": "http://localhost:9000"
|
||||
},
|
||||
"productName": "nym-wallet",
|
||||
"mainBinaryName": "nym-wallet",
|
||||
"version": "1.2.15",
|
||||
"identifier": "net.nymtech.wallet",
|
||||
"plugins": {
|
||||
"updater": {
|
||||
"active": true,
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IENCNzQ2M0E5N0VFODE2NApSV1JrZ2U2WE9rYTNETTg1OTBKdE5uWUEra0hML2syOVUvQ2lxZmFZRzZ1T3NWbGM0eVRzUTVhVwo=",
|
||||
"endpoints": [
|
||||
"https://nymtech.net/.wellknown/wallet/updater.json"
|
||||
],
|
||||
"dialog": true,
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IENCNzQ2M0E5N0VFODE2NApSV1JrZ2U2WE9rYTNETTg1OTBKdE5uWUEra0hML2syOVUvQ2lxZmFZRzZ1T3NWbGM0eVRzUTVhVwo="
|
||||
},
|
||||
"allowlist": {
|
||||
"window": {
|
||||
"maximize": true,
|
||||
"print": true
|
||||
},
|
||||
"clipboard": {
|
||||
"all": true
|
||||
},
|
||||
"shell": {
|
||||
"open": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'; connect-src ipc: http://ipc.localhost"
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "Nym Wallet",
|
||||
"width": 1268,
|
||||
"height": 768,
|
||||
"resizable": true
|
||||
"resizable": true,
|
||||
"useHttpsScheme": true
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, IconButton, Tooltip } from '@mui/material';
|
||||
import { Check, ContentCopy } from '@mui/icons-material';
|
||||
import { clipboard } from '@tauri-apps/api';
|
||||
import { Console } from '../utils/console';
|
||||
import { writeText, readText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
|
||||
export const CopyToClipboard = ({ text = '', iconButton }: { text?: string; iconButton?: boolean }) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleCopy = async (_text: string) => {
|
||||
try {
|
||||
await clipboard.writeText(_text);
|
||||
await writeText(_text);
|
||||
setCopied(true);
|
||||
} catch (e) {
|
||||
Console.error(`failed to copy: ${e}`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Button, Stack, Typography } from '@mui/material';
|
||||
import { checkUpdate } from '@tauri-apps/api/updater';
|
||||
import { check } from '@tauri-apps/plugin-updater';
|
||||
import { AppContext } from '../../context';
|
||||
import { checkVersion } from '../../requests';
|
||||
import { Console } from '../../utils/console';
|
||||
@@ -28,7 +28,7 @@ const AppVersion = () => {
|
||||
try {
|
||||
// despite the name, this will spawn an external native window with
|
||||
// an embedded "download and update the Wallet" flow
|
||||
checkUpdate();
|
||||
check();
|
||||
} catch (e) {
|
||||
Console.error(e);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable react/destructuring-assignment */
|
||||
import React from 'react';
|
||||
import { Button, Card, CardContent, TextField } from '@mui/material';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
|
||||
interface DocEntryProps {
|
||||
function: FunctionDef;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { config } from '../config';
|
||||
import { Console } from '../utils/console';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { appWindow } from '@tauri-apps/api/window';
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
import bs58 from 'bs58';
|
||||
import Big from 'big.js';
|
||||
import { valid } from 'semver';
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
userBalance,
|
||||
} from '../requests';
|
||||
import { Console } from './console';
|
||||
const appWindow = getCurrentWebviewWindow()
|
||||
|
||||
export const validateKey = (key: string, bytesLength: number): boolean => {
|
||||
// it must be a valid base58 key
|
||||
|
||||
Reference in New Issue
Block a user