From 6a01edf5feb5eaab9132389c9409fd076db8604b Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Wed, 29 Jun 2022 16:20:01 +0100 Subject: [PATCH 1/4] Nym Connect: fetch list of services from wellknown location and let the user choose --- nym-connect/Cargo.lock | 1 + nym-connect/src-tauri/Cargo.toml | 1 + nym-connect/src-tauri/src/error.rs | 5 + nym-connect/src-tauri/src/main.rs | 1 + nym-connect/src-tauri/src/models/mod.rs | 20 ++++ .../src-tauri/src/operations/directory/mod.rs | 14 +++ nym-connect/src-tauri/src/operations/mod.rs | 1 + nym-connect/src/App.tsx | 12 +- nym-connect/src/components/AppWindowFrame.tsx | 10 +- .../src/components/ConnectionButton.tsx | 15 ++- .../src/components/ConnectionStatus.tsx | 21 ++-- .../components/ServiceProviderSelector.tsx | 110 ++++++++++++++++++ nym-connect/src/context/main.tsx | 21 ++++ nym-connect/src/layouts/ConnectedLayout.tsx | 8 +- nym-connect/src/layouts/DefaultLayout.tsx | 42 +++++-- nym-connect/src/stories/AppFlow.stories.tsx | 22 +++- nym-connect/src/types/directory.ts | 14 +++ 17 files changed, 282 insertions(+), 36 deletions(-) create mode 100644 nym-connect/src-tauri/src/operations/directory/mod.rs create mode 100644 nym-connect/src/components/ServiceProviderSelector.tsx create mode 100644 nym-connect/src/types/directory.ts diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 7b50a712f9..39072331f0 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -3385,6 +3385,7 @@ dependencies = [ "nym-socks5-client", "pretty_env_logger", "rand 0.7.3", + "reqwest", "serde", "serde_json", "tauri", diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index 92e555b322..e45da2ce06 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -35,6 +35,7 @@ url = "2.2" log = "0.4" pretty_env_logger = "0.4.0" fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"} +reqwest = { version = "0.11", features = ["json"] } client-core = { path = "../../clients/client-core" } config = { path = "../../common/config" } diff --git a/nym-connect/src-tauri/src/error.rs b/nym-connect/src-tauri/src/error.rs index c56c1e488e..e14bd47264 100644 --- a/nym-connect/src-tauri/src/error.rs +++ b/nym-connect/src-tauri/src/error.rs @@ -14,6 +14,11 @@ pub enum BackendError { NoServiceProviderSet, #[error("No gateway provider set")] NoGatewaySet, + #[error("{source}")] + ReqwestError { + #[from] + source: reqwest::Error, + }, } impl Serialize for BackendError { diff --git a/nym-connect/src-tauri/src/main.rs b/nym-connect/src-tauri/src/main.rs index 84e862dc00..8f74d60429 100644 --- a/nym-connect/src-tauri/src/main.rs +++ b/nym-connect/src-tauri/src/main.rs @@ -42,6 +42,7 @@ fn main() { crate::operations::connection::connect::start_connecting, crate::operations::connection::disconnect::start_disconnecting, crate::operations::window::hide_window, + crate::operations::directory::get_services, ]) .menu(Menu::new().add_default_app_submenu_if_macos()) .system_tray(create_tray_menu()) diff --git a/nym-connect/src-tauri/src/models/mod.rs b/nym-connect/src-tauri/src/models/mod.rs index c7cda22fec..5ecdbf5c50 100644 --- a/nym-connect/src-tauri/src/models/mod.rs +++ b/nym-connect/src-tauri/src/models/mod.rs @@ -30,3 +30,23 @@ pub const APP_EVENT_CONNECTION_STATUS_CHANGED: &str = "app:connection-status-cha pub struct AppEventConnectionStatusChangedPayload { pub status: ConnectionStatusKind, } + +#[cfg_attr(test, derive(ts_rs::TS))] +#[derive(Clone, serde::Serialize, serde::Deserialize)] +pub struct DirectoryService { + pub id: String, + pub description: String, + pub items: Vec, +} + +#[cfg_attr(test, derive(ts_rs::TS))] +#[derive(Clone, serde::Serialize, serde::Deserialize)] +pub struct DirectoryServiceProvider { + pub id: String, + pub description: String, + /// Address of the network requester in the form "." + /// e.g. DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh + pub address: String, + /// Address of the gateway, e.g. 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh + pub gateway: String, +} diff --git a/nym-connect/src-tauri/src/operations/directory/mod.rs b/nym-connect/src-tauri/src/operations/directory/mod.rs new file mode 100644 index 0000000000..1088c37f8b --- /dev/null +++ b/nym-connect/src-tauri/src/operations/directory/mod.rs @@ -0,0 +1,14 @@ +use crate::error::BackendError; +use crate::models::DirectoryService; + +static SERVICE_PROVIDER_WELLKNOWN_URL: &str = + "https://nymtech.net/.wellknown/connect/service-providers.json"; + +#[tauri::command] +pub async fn get_services() -> Result, BackendError> { + let res = reqwest::get(SERVICE_PROVIDER_WELLKNOWN_URL) + .await? + .json::>() + .await?; + Ok(res) +} diff --git a/nym-connect/src-tauri/src/operations/mod.rs b/nym-connect/src-tauri/src/operations/mod.rs index 7f7e1771bf..c4a21fb7c9 100644 --- a/nym-connect/src-tauri/src/operations/mod.rs +++ b/nym-connect/src-tauri/src/operations/mod.rs @@ -1,2 +1,3 @@ pub mod connection; +pub mod directory; pub mod window; diff --git a/nym-connect/src/App.tsx b/nym-connect/src/App.tsx index 043d5f4642..10a2995f34 100644 --- a/nym-connect/src/App.tsx +++ b/nym-connect/src/App.tsx @@ -7,6 +7,7 @@ import { ConnectedLayout } from './layouts/ConnectedLayout'; export const App: React.FC = () => { const context = useClientContext(); const [busy, setBusy] = React.useState(); + const handleConnectClick = React.useCallback(async () => { const oldStatus = context.connectionStatus; if (oldStatus === ConnectionStatusKind.connected || oldStatus === ConnectionStatusKind.disconnected) { @@ -29,7 +30,15 @@ export const App: React.FC = () => { context.connectionStatus === ConnectionStatusKind.disconnected || context.connectionStatus === ConnectionStatusKind.connecting ) { - return ; + return ( + + ); } return ( @@ -40,6 +49,7 @@ export const App: React.FC = () => { ipAddress="127.0.0.1" port={1080} connectedSince={context.connectedSince} + serviceProvider={context.serviceProvider} stats={[ { label: 'in:', diff --git a/nym-connect/src/components/AppWindowFrame.tsx b/nym-connect/src/components/AppWindowFrame.tsx index 93b405ca50..c1fc63626b 100644 --- a/nym-connect/src/components/AppWindowFrame.tsx +++ b/nym-connect/src/components/AppWindowFrame.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { Box } from '@mui/material'; -import { invoke } from '@tauri-apps/api/tauri'; export const AppWindowFrame: React.FC = ({ children }) => ( ( }} > - - + + + + {children} diff --git a/nym-connect/src/components/ConnectionButton.tsx b/nym-connect/src/components/ConnectionButton.tsx index 05552edee8..7fe96c6da8 100644 --- a/nym-connect/src/components/ConnectionButton.tsx +++ b/nym-connect/src/components/ConnectionButton.tsx @@ -3,17 +3,21 @@ import { ConnectionStatusKind } from '../types'; export const ConnectionButton: React.FC<{ status: ConnectionStatusKind; + disabled?: boolean; busy?: boolean; isError?: boolean; onClick?: (status: ConnectionStatusKind) => void; -}> = ({ status, isError, onClick, busy }) => { +}> = ({ status, disabled, isError, onClick, busy }) => { const [hover, setHover] = React.useState(false); const handleClick = React.useCallback(() => { + if (disabled === true) { + return; + } if (onClick) { onClick(status); } - }, [status]); + }, [status, disabled]); const statusText = getStatusText(status, hover); const statusTextColor = isError ? '#40475C' : '#FFF'; @@ -21,16 +25,17 @@ export const ConnectionButton: React.FC<{ return ( setHover(true)} - onMouseLeave={() => setHover(false)} + onMouseEnter={() => !disabled && setHover(true)} + onMouseLeave={() => !disabled && setHover(false)} > - + diff --git a/nym-connect/src/components/ConnectionStatus.tsx b/nym-connect/src/components/ConnectionStatus.tsx index 20e778e0ff..a866f8521d 100644 --- a/nym-connect/src/components/ConnectionStatus.tsx +++ b/nym-connect/src/components/ConnectionStatus.tsx @@ -4,6 +4,7 @@ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import CircleOutlinedIcon from '@mui/icons-material/CircleOutlined'; import { DateTime } from 'luxon'; import { ConnectionStatusKind } from '../types'; +import { ServiceProvider } from '../types/directory'; const FONT_SIZE = '16px'; const FONT_WEIGHT = '600'; @@ -57,7 +58,8 @@ const ConnectionStatusContent: React.FC<{ export const ConnectionStatus: React.FC<{ status: ConnectionStatusKind; connectedSince?: DateTime; -}> = ({ status, connectedSince }) => { + serviceProvider?: ServiceProvider; +}> = ({ status, connectedSince, serviceProvider }) => { const color = status === ConnectionStatusKind.connected || status === ConnectionStatusKind.disconnecting ? '#21D072' : '#888'; const [duration, setDuration] = React.useState(); @@ -72,13 +74,16 @@ export const ConnectionStatus: React.FC<{ }; }, [status, connectedSince]); return ( - - - + <> + + + + + + {status === ConnectionStatusKind.connected && duration} + - - {status === ConnectionStatusKind.connected && duration} - - + {serviceProvider && {serviceProvider.description}} + ); }; diff --git a/nym-connect/src/components/ServiceProviderSelector.tsx b/nym-connect/src/components/ServiceProviderSelector.tsx new file mode 100644 index 0000000000..8e46cd5b03 --- /dev/null +++ b/nym-connect/src/components/ServiceProviderSelector.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import IconButton from '@mui/material/IconButton'; +import Menu from '@mui/material/Menu'; +import MenuItem from '@mui/material/MenuItem'; +import ArrowDropDownCircleIcon from '@mui/icons-material/ArrowDropDownCircle'; +import { Box, CircularProgress, Stack, Tooltip, Typography } from '@mui/material'; +import { ServiceProvider, Services } from '../types/directory'; + +export const ServiceProviderSelector: React.FC<{ + onChange?: (serviceProvider: ServiceProvider) => void; + services?: Services; +}> = ({ services, onChange }) => { + const [serviceProvider, setServiceProvider] = React.useState(); + const textEl = React.useRef(null); + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = () => { + setAnchorEl(textEl.current); + }; + const handleClose = (newServiceProvider?: ServiceProvider) => { + if (newServiceProvider) { + setServiceProvider(newServiceProvider); + onChange?.(newServiceProvider); + } + setAnchorEl(null); + }; + + if (!services) { + return ( + + theme.palette.common.white}> + + Loading services... + + + + + + ); + } + + return ( + <> + + (serviceProvider ? undefined : theme.palette.primary.main)} + > + {serviceProvider ? serviceProvider.description : 'Select a service'} + + + + + + handleClose()} + MenuListProps={{ + 'aria-labelledby': 'service-provider-button', + }} + > + {services.map((service) => ( + <> + + {service.description} + + {service.items.map((sp) => ( + handleClose(sp)}> + + + {sp.id} + + + {sp.description} + + + Gateway {sp.gateway.slice(0, 10)}... + + + Provider {sp.address.slice(0, 10)}... + + + } + arrow + placement="top" + > + + {sp.description} + + + + ))} + + ))} + + + ); +}; diff --git a/nym-connect/src/context/main.tsx b/nym-connect/src/context/main.tsx index 33e508733a..066d4400d2 100644 --- a/nym-connect/src/context/main.tsx +++ b/nym-connect/src/context/main.tsx @@ -4,6 +4,7 @@ import { invoke } from '@tauri-apps/api/tauri'; import { listen, UnlistenFn } from '@tauri-apps/api/event'; import { ConnectionStatusKind } from '../types'; import { ConnectionStatsItem } from '../components/ConnectionStats'; +import { ServiceProvider, Services } from '../types/directory'; const TAURI_EVENT_STATUS_CHANGED = 'app:connection-status-changed'; @@ -14,11 +15,14 @@ type TClientContext = { connectionStatus: ConnectionStatusKind; connectionStats?: ConnectionStatsItem[]; connectedSince?: DateTime; + services?: Services; + serviceProvider?: ServiceProvider; setMode: (mode: ModeType) => void; setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void; setConnectionStats: (connectionStats: ConnectionStatsItem[] | undefined) => void; setConnectedSince: (connectedSince: DateTime | undefined) => void; + setServiceProvider: (serviceProvider: ServiceProvider) => void; startConnecting: () => Promise; startDisconnecting: () => Promise; @@ -31,6 +35,14 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode const [connectionStatus, setConnectionStatus] = useState(ConnectionStatusKind.disconnected); const [connectionStats, setConnectionStats] = useState(); const [connectedSince, setConnectedSince] = useState(); + const [services, setServices] = React.useState(); + const [serviceProvider, setRawServiceProvider] = React.useState(); + + useEffect(() => { + invoke('get_services').then((result) => { + setServices(result as Services); + }); + }, []); useEffect(() => { let unlisten: UnlistenFn | undefined; @@ -59,6 +71,12 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode await invoke('start_disconnecting'); }, []); + const setServiceProvider = useCallback(async (newServiceProvider: ServiceProvider) => { + await invoke('set_gateway', { gateway: newServiceProvider.gateway }); + await invoke('set_service_provider', { serviceProvider: newServiceProvider.address }); + setRawServiceProvider(newServiceProvider); + }, []); + return ( {children} diff --git a/nym-connect/src/layouts/ConnectedLayout.tsx b/nym-connect/src/layouts/ConnectedLayout.tsx index bf838619a9..a031f18a56 100644 --- a/nym-connect/src/layouts/ConnectedLayout.tsx +++ b/nym-connect/src/layouts/ConnectedLayout.tsx @@ -8,6 +8,7 @@ import { ConnectionStats, ConnectionStatsItem } from '../components/ConnectionSt import { NeedHelp } from '../components/NeedHelp'; import { ConnectionButton } from '../components/ConnectionButton'; import { IpAddressAndPort } from '../components/IpAddressAndPort'; +import { ServiceProvider } from '../types/directory'; export const ConnectedLayout: React.FC<{ status: ConnectionStatusKind; @@ -18,15 +19,16 @@ export const ConnectedLayout: React.FC<{ busy?: boolean; isError?: boolean; onConnectClick?: (status: ConnectionStatusKind) => void; -}> = ({ status, stats, ipAddress, port, connectedSince, busy, isError, onConnectClick }) => ( + serviceProvider?: ServiceProvider; +}> = ({ status, stats, ipAddress, port, connectedSince, busy, isError, serviceProvider, onConnectClick }) => ( - + - + {/* */} diff --git a/nym-connect/src/layouts/DefaultLayout.tsx b/nym-connect/src/layouts/DefaultLayout.tsx index 1e38154bd3..42b6357442 100644 --- a/nym-connect/src/layouts/DefaultLayout.tsx +++ b/nym-connect/src/layouts/DefaultLayout.tsx @@ -4,21 +4,39 @@ import { AppWindowFrame } from '../components/AppWindowFrame'; import { ConnectionButton } from '../components/ConnectionButton'; import { ConnectionStatusKind } from '../types'; import { NeedHelp } from '../components/NeedHelp'; +import { ServiceProviderSelector } from '../components/ServiceProviderSelector'; +import { ServiceProvider, Services } from '../types/directory'; export const DefaultLayout: React.FC<{ status: ConnectionStatusKind; + services?: Services; busy?: boolean; isError?: boolean; onConnectClick?: (status: ConnectionStatusKind) => void; -}> = ({ status, busy, isError, onConnectClick }) => ( - - - Connect, your privacy will be 100% protected thanks to the Nym Mixnet - - - You are not protected now - - - - -); + onServiceProviderChange?: (serviceProvider: ServiceProvider) => void; +}> = ({ status, services, busy, isError, onConnectClick, onServiceProviderChange }) => { + const [serviceProvider, setServiceProvider] = React.useState(); + const handleServiceProviderChange = (newServiceProvider: ServiceProvider) => { + setServiceProvider(newServiceProvider); + onServiceProviderChange?.(newServiceProvider); + }; + return ( + + + Connect, your privacy will be 100% protected thanks to the Nym Mixnet + + + You are not protected now + + + + + + ); +}; diff --git a/nym-connect/src/stories/AppFlow.stories.tsx b/nym-connect/src/stories/AppFlow.stories.tsx index 72ca502466..25c8ba8b8e 100644 --- a/nym-connect/src/stories/AppFlow.stories.tsx +++ b/nym-connect/src/stories/AppFlow.stories.tsx @@ -7,6 +7,7 @@ import { useClientContext } from '../context/main'; import { ConnectionStatusKind } from '../types'; import { DefaultLayout } from '../layouts/DefaultLayout'; import { ConnectedLayout } from '../layouts/ConnectedLayout'; +import { Services } from '../types/directory'; export default { title: 'App/Flow', @@ -16,6 +17,19 @@ export default { export const Mock: ComponentStory = () => { const context = useClientContext(); const [busy, setBusy] = React.useState(); + const services: Services = [ + { + id: 'keybase', + description: 'Keybase', + items: [ + { + id: 'nym-keybase', + description: 'Nym Keybase Service Provider', + address: '1234.5678', + }, + ], + }, + ]; const handleConnectClick = React.useCallback(() => { const oldStatus = context.connectionStatus; if (oldStatus === ConnectionStatusKind.connected || oldStatus === ConnectionStatusKind.disconnected) { @@ -53,7 +67,12 @@ export const Mock: ComponentStory = () => { ) { return ( - + ); } @@ -67,6 +86,7 @@ export const Mock: ComponentStory = () => { ipAddress="127.0.0.1" port={1080} connectedSince={context.connectedSince} + serviceProvider={services[0].items[0]} stats={[ { label: 'in:', diff --git a/nym-connect/src/types/directory.ts b/nym-connect/src/types/directory.ts new file mode 100644 index 0000000000..55395192a1 --- /dev/null +++ b/nym-connect/src/types/directory.ts @@ -0,0 +1,14 @@ +export interface ServiceProvider { + id: string; + description: string; + address: string; + gateway: string; +} + +export interface Service { + id: string; + description: string; + items: ServiceProvider[]; +} + +export type Services = Service[]; From de605dc3b960554cd50b3057dd8f24f3764da0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Wed, 29 Jun 2022 23:25:03 +0200 Subject: [PATCH 2/4] connect: append gateway to id --- nym-connect/src-tauri/src/config/mod.rs | 67 +++++++++++++------ nym-connect/src-tauri/src/main.rs | 5 ++ .../src/operations/connection/connect.rs | 5 ++ nym-connect/src-tauri/src/state.rs | 34 +++++++--- 4 files changed, 80 insertions(+), 31 deletions(-) diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 93acea98e0..7b3009632e 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -2,31 +2,51 @@ use std::path::PathBuf; use client_core::config::GatewayEndpoint; use log::info; +use std::sync::Arc; +use tokio::sync::RwLock; use client_core::config::Config as BaseConfig; use config::NymConfig; use nym_socks5::client::config::Config as Socks5Config; -pub static SOCKS5_CONFIG_ID: &str = "nym-connect"; +use crate::{error::BackendError, state::State}; -// This is an open-proxy network-requester for testing -// TODO: make this configurable from the UI -// TODO: once we can set this is the UI, consider just removing it, and put in guards to halt if -// user hasn't chosen the provider -pub static PROVIDER_ADDRESS: &str = "8CrdmK4mYgZ5caMxGU4AvNeT1dXL8VSbgMYAjSFvnfut.2GLdZ1Jn9vkTBMf858evGNGDsPoeivUPw7zFNceLiLX3@BNjYZPxzcJwczXHHgBxCAyVJKxN6LPteDRrKapxWmexv"; +pub static SOCKS5_CONFIG_ID: &str = "nym-connect"; const DEFAULT_ETH_ENDPOINT: &str = "https://rinkeby.infura.io/v3/00000000000000000000000000000000"; const DEFAULT_ETH_PRIVATE_KEY: &str = "0000000000000000000000000000000000000000000000000000000000000001"; -#[tauri::command] -pub fn get_config_file_location() -> String { - let id: &str = SOCKS5_CONFIG_ID; - Config::config_file_location(id) - .to_string_lossy() - .to_string() +pub fn append_config_id(gateway_id: &str) -> String { + let mut id = SOCKS5_CONFIG_ID.to_string(); + id.push_str(&format!("-{}", gateway_id)); + id } +#[tauri::command] +pub async fn get_config_id( + state: tauri::State<'_, Arc>>, +) -> Result { + let guard = state.read().await; + // TODO: return error instead + let gateway_id = guard + .get_gateway() + .as_ref() + .expect("The config id can not be determined before setting the gateway"); + Ok(append_config_id(gateway_id)) +} + +#[tauri::command] +pub async fn get_config_file_location( + state: tauri::State<'_, Arc>>, +) -> Result { + let id = get_config_id(state).await?; + Ok(Config::config_file_location(&id) + .to_string_lossy() + .to_string()) +} + +#[derive(Debug)] pub struct Config { socks5: Socks5Config, } @@ -55,9 +75,7 @@ impl Config { self.socks5.get_base_mut() } - pub async fn init(service_provider: Option<&String>, chosen_gateway_id: Option<&String>) { - let service_provider = service_provider.map_or(PROVIDER_ADDRESS, String::as_str); - let chosen_gateway_id = chosen_gateway_id.map(String::as_str); + pub async fn init(service_provider: &str, chosen_gateway_id: &str) { info!("Initialising..."); init_socks5(service_provider, chosen_gateway_id).await; info!("Configuration saved 🚀"); @@ -68,16 +86,17 @@ impl Config { } } -pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str>) { +pub async fn init_socks5(provider_address: &str, chosen_gateway_id: &str) { log::info!("Initialising client..."); - let id: &str = SOCKS5_CONFIG_ID; + // Append the gateway id to the name id that we store the config under + let id = append_config_id(chosen_gateway_id); log::debug!( "Attempting to use config file location: {}", - Config::config_file_location(id).to_string_lossy(), + Config::config_file_location(&id).to_string_lossy(), ); - let already_init = Config::config_file_location(id).exists(); + let already_init = Config::config_file_location(&id).exists(); if already_init { log::info!( "SOCKS5 client \"{}\" was already initialised before! \ @@ -92,7 +111,7 @@ pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str> let register_gateway = !already_init || user_wants_force_register; log::trace!("Creating config for id: {}", id); - let mut config = Config::new(id, provider_address); + let mut config = Config::new(id.as_str(), provider_address); // As far as I'm aware, these two are not used, they are only set because the socks5 init code // requires them for initialising the bandwidth controller. @@ -103,7 +122,13 @@ pub async fn init_socks5(provider_address: &str, chosen_gateway_id: Option<&str> .get_base_mut() .with_eth_private_key(DEFAULT_ETH_PRIVATE_KEY); - let gateway = setup_gateway(id, register_gateway, chosen_gateway_id, config.get_socks5()).await; + let gateway = setup_gateway( + &id, + register_gateway, + Some(chosen_gateway_id), + config.get_socks5(), + ) + .await; config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_socks5().get_config_file_save_location(); diff --git a/nym-connect/src-tauri/src/main.rs b/nym-connect/src-tauri/src/main.rs index 8f74d60429..1496aa6f4b 100644 --- a/nym-connect/src-tauri/src/main.rs +++ b/nym-connect/src-tauri/src/main.rs @@ -35,6 +35,7 @@ fn main() { .manage(Arc::new(RwLock::new(State::new()))) .invoke_handler(tauri::generate_handler![ crate::config::get_config_file_location, + crate::config::get_config_id, crate::operations::connection::connect::get_gateway, crate::operations::connection::connect::get_service_provider, crate::operations::connection::connect::set_gateway, @@ -62,5 +63,9 @@ fn setup_logging() { log_builder .filter_module("handlebars", log::LevelFilter::Warn) + .filter_module("mio", log::LevelFilter::Warn) + .filter_module("sled", log::LevelFilter::Warn) + .filter_module("tokio_tungstenite", log::LevelFilter::Warn) + .filter_module("tungstenite", log::LevelFilter::Warn) .init(); } diff --git a/nym-connect/src-tauri/src/operations/connection/connect.rs b/nym-connect/src-tauri/src/operations/connection/connect.rs index 6ffb583be3..b28913472f 100644 --- a/nym-connect/src-tauri/src/operations/connection/connect.rs +++ b/nym-connect/src-tauri/src/operations/connection/connect.rs @@ -11,6 +11,9 @@ pub async fn start_connecting( ) -> Result { let mut guard = state.write().await; + log::trace!("Start connecting with:"); + log::trace!(" service_provider: {:?}", guard.get_service_provider()); + log::trace!(" gateway: {:?}", guard.get_gateway()); guard.start_connecting(&window).await; Ok(ConnectResult { @@ -35,6 +38,7 @@ pub async fn set_service_provider( service_provider: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + log::trace!("Setting service_provider: {service_provider}"); let mut guard = state.write().await; guard.set_service_provider(service_provider); Ok(()) @@ -56,6 +60,7 @@ pub async fn set_gateway( gateway: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + log::trace!("Setting gateway: {gateway}"); let mut guard = state.write().await; guard.set_gateway(gateway); Ok(()) diff --git a/nym-connect/src-tauri/src/state.rs b/nym-connect/src-tauri/src/state.rs index b52d7fd31b..a367cb01ff 100644 --- a/nym-connect/src-tauri/src/state.rs +++ b/nym-connect/src-tauri/src/state.rs @@ -8,10 +8,12 @@ use config::NymConfig; use nym_socks5::client::NymClient as Socks5NymClient; use nym_socks5::client::{Socks5ControlMessage, Socks5ControlMessageSender}; -use crate::config::SOCKS5_CONFIG_ID; -use crate::models::{ - AppEventConnectionStatusChangedPayload, ConnectionStatusKind, - APP_EVENT_CONNECTION_STATUS_CHANGED, +use crate::{ + config::append_config_id, + models::{ + AppEventConnectionStatusChangedPayload, ConnectionStatusKind, + APP_EVENT_CONNECTION_STATUS_CHANGED, + }, }; use tauri::Manager; @@ -64,7 +66,15 @@ impl State { } pub async fn init_config(&self) { - crate::config::Config::init(self.service_provider.as_ref(), self.gateway.as_ref()).await; + let service_provider = self + .service_provider + .as_ref() + .expect("Attempting to init without service provider"); + let gateway = self + .gateway + .as_ref() + .expect("Attempting to init without gateway"); + crate::config::Config::init(service_provider, gateway).await; } pub async fn start_connecting(&mut self, window: &tauri::Window) { @@ -76,7 +86,12 @@ impl State { self.init_config().await; // Kick of the main task and get the channel for controlling it - let (sender, used_gateway) = start_nym_socks5_client(); + let id = append_config_id( + self.gateway + .as_ref() + .expect("Attempting to start without gateway"), + ); + let (sender, used_gateway) = start_nym_socks5_client(&id); self.gateway = Some(used_gateway.gateway_id); self.socks5_client_sender = Some(sender); @@ -99,10 +114,9 @@ impl State { } } -fn start_nym_socks5_client() -> (Socks5ControlMessageSender, GatewayEndpoint) { - let id: &str = SOCKS5_CONFIG_ID; - - info!("Loading config from file"); +fn start_nym_socks5_client(id: &str) -> (Socks5ControlMessageSender, GatewayEndpoint) { + info!("Loading config from file: {id}"); + // TODO: handle this gracefully! let config = nym_socks5::client::config::Config::load_from_file(Some(id)).unwrap(); let used_gateway = config.get_base().get_gateway_endpoint().clone(); From 5ebb2a3efefd56fdd7ab3573d12d93f7c3c7611c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Mon, 4 Jul 2022 15:06:23 +0200 Subject: [PATCH 3/4] changelog: add note --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cddf23bd5d..3fa7ce698b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - socks5 client/websocket client: add `--force-register-gateway` flag, useful when rerunning init ([#1353]) - nym-connect: initial proof-of-concept of a UI around the socks5 client was added +- nym-connect: add ability to select network requester and gateway ([#1427]). - all: added network compilation target to `--help` (or `--version`) commands ([#1256]). - explorer-api: learned how to sum the delegations by owner in a new endpoint. - explorer-api: add apy values to `mix_nodes` endpoint @@ -63,6 +64,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// [#1388]: https://github.com/nymtech/nym/pull/1388 [#1393]: https://github.com/nymtech/nym/pull/1393 [#1404]: https://github.com/nymtech/nym/pull/1404 +[#1427]: https://github.com/nymtech/nym/pull/1427 ## [nym-contracts-v1.0.1](https://github.com/nymtech/nym/tree/nym-contracts-v1.0.1) (2022-06-22) From 0fbe77d934eb72ba5a8c29719d2f0ed54d41e873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Mon, 4 Jul 2022 15:23:14 +0200 Subject: [PATCH 4/4] connect: clippy --- nym-connect/src-tauri/src/config/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 7b3009632e..008e8a2086 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -18,8 +18,9 @@ const DEFAULT_ETH_PRIVATE_KEY: &str = "0000000000000000000000000000000000000000000000000000000000000001"; pub fn append_config_id(gateway_id: &str) -> String { + use std::fmt::Write as _; let mut id = SOCKS5_CONFIG_ID.to_string(); - id.push_str(&format!("-{}", gateway_id)); + write!(id, "-{}", gateway_id).expect("Failed to set config id"); id }