diff --git a/.env.sample-dev b/.env.sample-dev index d77245ab12..3a48d8ebb0 100644 --- a/.env.sample-dev +++ b/.env.sample-dev @@ -14,7 +14,7 @@ GEOIPUPDATE_LICENSE_KEY=xxx # List of space-separated database edition IDs. Edition IDs may # consist of letters, digits, and dashes. For example, GeoIP2-City # would download the GeoIP2 City database (GeoIP2-City). -GEOIPUPDATE_EDITION_IDS=GeoLite2-Country +GEOIPUPDATE_EDITION_IDS=GeoLite2-City # The number of hours between geoipupdate runs. If this is not set # or is set to 0, geoipupdate will run once and exit. GEOIPUPDATE_FREQUENCY=72 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a372b8376..a5080d62aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,26 +6,37 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ### Added -- socks5: send status message for service ready, and network-requester error response - ### Changed - renamed all references to validator_api to nym_api - renamed all references to nymd to nyxd -- all-binaries: improved error logging ([#2686]) -- native client: bring shutdown logic up to the same level as socks5-client -- nym-api, coconut-dkg contract: automatic, time-based dkg epoch state advancement ([#2670]) - all-binaries: standarised argument names (note: old names should still be accepted) ([#2762] ### Fixed - nym-api: should now correctly use `rewarding.enabled` config flag ([#2753]) -[#2686]: https://github.com/nymtech/nym/pull/2686 -[#2670]: https://github.com/nymtech/nym/pull/2670 [#2753]: https://github.com/nymtech/nym/pull/2753 [#2762]: https://github.com/nymtech/nym/pull/2762 +## [v1.1.5] (2022-01-10) + +### Added + +- socks5: send status message for service ready, and network-requester error response in https://github.com/nymtech/nym/pull/2715 + +### Changed + +- all-binaries: improved error logging in https://github.com/nymtech/nym/pull/2686 +- native client: bring shutdown logic up to the same level as socks5-client in https://github.com/nymtech/nym/pull/2695 +- nym-api, coconut-dkg contract: automatic, time-based dkg epoch state advancement in https://github.com/nymtech/nym/pull/2670 +- DKG resharing unit test by @neacsu in https://github.com/nymtech/nym/pull/2668 +- Renaming validator-api to nym-api by @futurechimp in https://github.com/nymtech/nym/pull/1863 +- Modify wasm specific make targets by @neacsu in https://github.com/nymtech/nym/pull/2693 +- client: create websocket handler builder by @octol in https://github.com/nymtech/nym/pull/2700 +- Outfox and Lion by @durch in https://github.com/nymtech/nym/pull/2730 +- Feature/multi surb transmission lanes by @jstuczyn in https://github.com/nymtech/nym/pull/2723 + ## [v1.1.4] (2022-12-20) This release adds multiple Single Use Reply Blocks (SURBs) to allow arbitrarily-sized anonymized replies. diff --git a/clients/client-core/Cargo.toml b/clients/client-core/Cargo.toml index 2c36fb892b..507552e887 100644 --- a/clients/client-core/Cargo.toml +++ b/clients/client-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "client-core" -version = "1.1.4" +version = "1.1.5" authors = ["Dave Hrycyszyn "] edition = "2021" rust-version = "1.66" diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 27f13bbbc4..961dd8333c 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.4" +version = "1.1.5" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index c4218c45e4..4a20ac946e 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.4" +version = "1.1.5" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/explorer-api/.env.sample b/explorer-api/.env.sample index 1efd2de597..e5922f9cf0 100644 --- a/explorer-api/.env.sample +++ b/explorer-api/.env.sample @@ -1,2 +1,2 @@ # The path to the geoip database file -GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb +GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index 129423cf7f..eb4b6ac83f 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "explorer-api" -version = "1.1.1" +version = "1.1.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/explorer-api/README.md b/explorer-api/README.md index d4e193dbb0..86e64e4c12 100644 --- a/explorer-api/README.md +++ b/explorer-api/README.md @@ -40,7 +40,7 @@ It should be previously installed thanks to `geoipupdate` service. For example: ```shell -GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb cargo run +GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb cargo run ``` Note: explorer-api binary reads the provided `.env` file. diff --git a/explorer-api/src/buy_terms/http.rs b/explorer-api/src/buy_terms/http.rs deleted file mode 100644 index 5594a1a3be..0000000000 --- a/explorer-api/src/buy_terms/http.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::geo_ip::location::Location; -use crate::state::ExplorerApiStateContext; -use rocket::response::status; -use rocket::serde::json::Json; -use rocket::{Route, State}; -use rocket_okapi::okapi::openapi3::OpenApi; -use rocket_okapi::settings::OpenApiSettings; - -pub fn nym_terms_make_default_routes(settings: &OpenApiSettings) -> (Vec, OpenApi) { - openapi_get_routes_spec![settings: terms] -} - -#[openapi(tag = "terms")] -#[get("/")] -pub(crate) async fn terms( - _state: &State, - location: Location, -) -> Result, status::Forbidden> { - if location.iso_alpha2 == "US" { - return Err(status::Forbidden(Some("US government sucks".to_string()))); - } - Ok(Json("Nym Terms & Conditions: Welcome".to_string())) -} diff --git a/explorer-api/src/buy_terms/mod.rs b/explorer-api/src/buy_terms/mod.rs deleted file mode 100644 index d064c8bd6f..0000000000 --- a/explorer-api/src/buy_terms/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod http; diff --git a/explorer-api/src/geo_ip/location.rs b/explorer-api/src/geo_ip/location.rs index a1afec55d6..adbdb6cef3 100644 --- a/explorer-api/src/geo_ip/location.rs +++ b/explorer-api/src/geo_ip/location.rs @@ -3,14 +3,14 @@ use isocountry::CountryCode; use log::warn; -use maxminddb::{geoip2::Country, MaxMindDBError, Reader}; +use maxminddb::{geoip2::City, MaxMindDBError, Reader}; use std::{ net::{IpAddr, ToSocketAddrs}, str::FromStr, sync::Arc, }; -const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-Country.mmdb"; +const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-City.mmdb"; const FAKE_PORT: u16 = 1234; #[derive(Debug)] @@ -38,6 +38,8 @@ pub(crate) struct Location { pub(crate) iso_alpha3: String, /// English country short name (ISO 3166-1) pub(crate) name: String, + pub(crate) latitude: Option, + pub(crate) longitude: Option, } impl GeoIp { @@ -86,7 +88,7 @@ impl GeoIp { error!("No registered GeoIP database"); GeoIpError::InternalError })? - .lookup::(ip); + .lookup::(ip); match &result { Ok(v) => Ok(Some( Location::try_from(v).map_err(|_| GeoIpError::InternalError)?, @@ -99,11 +101,11 @@ impl GeoIp { } } -impl<'a> TryFrom<&Country<'a>> for Location { +impl<'a> TryFrom<&City<'a>> for Location { type Error = String; - fn try_from(country: &Country) -> Result { - let data = country.country.as_ref().ok_or_else(|| { + fn try_from(city: &City) -> Result { + let data = city.country.as_ref().ok_or_else(|| { warn!("No Country data found"); "No Country data found" })?; @@ -119,10 +121,13 @@ impl<'a> TryFrom<&Country<'a>> for Location { warn!("{}", &message); message })?; + Ok(Location { iso_alpha2, iso_alpha3: String::from(iso_codes.alpha3()), name: String::from(iso_codes.name()), + latitude: city.location.as_ref().and_then(|l| l.latitude), + longitude: city.location.as_ref().and_then(|l| l.longitude), }) } } diff --git a/explorer-api/src/http/mod.rs b/explorer-api/src/http/mod.rs index f5559124a5..31f638ee5f 100644 --- a/explorer-api/src/http/mod.rs +++ b/explorer-api/src/http/mod.rs @@ -5,7 +5,6 @@ use rocket::{Build, Request, Rocket}; use rocket_cors::{AllowedHeaders, AllowedOrigins}; use rocket_okapi::swagger_ui::make_swagger_ui; -use crate::buy_terms::http::nym_terms_make_default_routes; use crate::country_statistics::http::country_statistics_make_default_routes; use crate::gateways::http::gateways_make_default_routes; use crate::http::swagger::get_docs; @@ -57,7 +56,6 @@ fn configure_rocket(state: ExplorerApiStateContext) -> Rocket { "/overview" => overview_make_default_routes(&openapi_settings), "/ping" => ping_make_default_routes(&openapi_settings), "/validators" => validators_make_default_routes(&openapi_settings), - "/terms" => nym_terms_make_default_routes(&openapi_settings), }; building_rocket diff --git a/explorer-api/src/main.rs b/explorer-api/src/main.rs index ecfde18949..7f0195394d 100644 --- a/explorer-api/src/main.rs +++ b/explorer-api/src/main.rs @@ -10,7 +10,6 @@ use logging::setup_logging; use network_defaults::setup_env; use task::{wait_for_signal, TaskManager}; -mod buy_terms; pub(crate) mod cache; mod client; pub(crate) mod commands; diff --git a/explorer-api/src/mix_nodes/location.rs b/explorer-api/src/mix_nodes/location.rs index d14eaf771e..51c46261c6 100644 --- a/explorer-api/src/mix_nodes/location.rs +++ b/explorer-api/src/mix_nodes/location.rs @@ -36,6 +36,8 @@ pub(crate) struct Location { pub(crate) two_letter_iso_country_code: String, pub(crate) three_letter_iso_country_code: String, pub(crate) country_name: String, + pub(crate) latitude: Option, + pub(crate) longitude: Option, } impl Location { @@ -44,6 +46,8 @@ impl Location { country_name: location.name, two_letter_iso_country_code: location.iso_alpha2, three_letter_iso_country_code: location.iso_alpha3, + latitude: location.latitude, + longitude: location.longitude, } } } diff --git a/explorer/CHANGELOG.md b/explorer/CHANGELOG.md new file mode 100644 index 0000000000..e55425407b --- /dev/null +++ b/explorer/CHANGELOG.md @@ -0,0 +1,8 @@ +## UNRELEASED + +## [nym-explorer-v1.0.1](https://github.com/nymtech/nym/tree/nym-explorer-v1.0.1) (2023-01-10) + +- Feat/2161 ne gate version by @gala1234 in https://github.com/nymtech/nym/pull/2743 +- fix(explorer): set gateway bond 6 decimals by @doums in https://github.com/nymtech/nym/pull/2741 +- Feat/2130 tables update rebase by @gala1234 in https://github.com/nymtech/nym/pull/2742 +- fix(explorer,explorer-api): mixnode location by @doums in https://github.com/nymtech/nym-api diff --git a/explorer/package.json b/explorer/package.json index b314878308..2478774987 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -1,6 +1,6 @@ { "name": "@nym/network-explorer", - "version": "1.0.0", + "version": "1.0.1", "private": true, "license": "Apache-2.0", "dependencies": { diff --git a/explorer/src/components/DetailTable.tsx b/explorer/src/components/DetailTable.tsx index 1aab097a05..75aaae36ab 100644 --- a/explorer/src/components/DetailTable.tsx +++ b/explorer/src/components/DetailTable.tsx @@ -5,7 +5,7 @@ import { Tooltip } from '@nymproject/react/tooltip/Tooltip'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { Box } from '@mui/system'; import { cellStyles } from './Universal-DataGrid'; -import { currencyToString } from '../utils/currency'; +import { unymToNym } from '../utils/currency'; import { GatewayEnrichedRowType } from './Gateways'; import { MixnodeRowType } from './MixNodes'; @@ -38,7 +38,7 @@ function formatCellValues(val: string | number, field: string) { ); } if (field === 'bond') { - return currencyToString(val.toString()); + return unymToNym(val, 6); } return val; } diff --git a/explorer/src/components/Gateways.ts b/explorer/src/components/Gateways.ts index e75c9aeb05..aa055a71d0 100644 --- a/explorer/src/components/Gateways.ts +++ b/explorer/src/components/Gateways.ts @@ -7,6 +7,7 @@ export type GatewayRowType = { bond: number; host: string; location: string; + version: string; }; export type GatewayEnrichedRowType = GatewayRowType & { @@ -26,6 +27,7 @@ export function gatewayToGridRow(arrayOfGateways: GatewayResponse): GatewayRowTy location: gw?.gateway?.location || '', bond: gw.pledge_amount.amount || 0, host: gw.gateway.host || '', + version: gw.gateway.version || '', })); } @@ -40,6 +42,7 @@ export function gatewayEnrichedToGridRow( location: gateway?.gateway?.location || '', bond: gateway.pledge_amount.amount || 0, host: gateway.gateway.host || '', + version: gateway.gateway.version || '', clientsPort: gateway.gateway.clients_port || 0, mixPort: gateway.gateway.mix_port || 0, routingScore: `${report.most_recent}%`, diff --git a/explorer/src/pages/GatewayDetail/index.tsx b/explorer/src/pages/GatewayDetail/index.tsx index 5fb7dd9c9f..3372ded2a7 100644 --- a/explorer/src/pages/GatewayDetail/index.tsx +++ b/explorer/src/pages/GatewayDetail/index.tsx @@ -58,6 +58,12 @@ const columns: ColumnsType[] = [ headerAlign: 'left', flex: 1, }, + { + field: 'version', + title: 'Version', + headerAlign: 'left', + flex: 1, + }, ]; /** diff --git a/explorer/src/pages/Gateways/index.tsx b/explorer/src/pages/Gateways/index.tsx index 2430e4f9a5..f35f7382b4 100644 --- a/explorer/src/pages/Gateways/index.tsx +++ b/explorer/src/pages/Gateways/index.tsx @@ -10,7 +10,7 @@ import { TableToolbar } from '../../components/TableToolbar'; import { CustomColumnHeading } from '../../components/CustomColumnHeading'; import { Title } from '../../components/Title'; import { cellStyles, UniversalDataGrid } from '../../components/Universal-DataGrid'; -import { currencyToString } from '../../utils/currency'; +import { unymToNym } from '../../utils/currency'; import { Tooltip } from '../../components/Tooltip'; import { BIG_DIPPER } from '../../api/constants'; import { splice } from '../../utils'; @@ -77,7 +77,7 @@ export const PageGateways: React.FC = () => { to={`/network-components/gateway/${params.row.identityKey}`} data-testid="pledge-amount" > - {currencyToString(params.value)} + {unymToNym(params.value, 6)} ), }, @@ -128,7 +128,7 @@ export const PageGateways: React.FC = () => { field: 'owner', headerName: 'Owner', renderHeader: () => , - width: 380, + width: 180, headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( @@ -142,6 +142,24 @@ export const PageGateways: React.FC = () => { ), }, + { + field: 'version', + headerName: 'Version', + renderHeader: () => , + width: 150, + headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', + renderCell: (params: GridRenderCellParams) => ( + + {params.value} + + ), + }, ]; const handlePageSize = (event: SelectChangeEvent) => { diff --git a/explorer/src/pages/MixnodeDetail/index.tsx b/explorer/src/pages/MixnodeDetail/index.tsx index 1c38f69a53..95e18ea603 100644 --- a/explorer/src/pages/MixnodeDetail/index.tsx +++ b/explorer/src/pages/MixnodeDetail/index.tsx @@ -164,10 +164,10 @@ const PageMixnodeDetailWithState: React.FC = () => { {mixNode && ( {mixNode?.error && } - {mixNode.data && mixNode?.data?.location && ( + {mixNode?.data?.location?.latitude && mixNode?.data?.location?.longitude && ( )} diff --git a/explorer/src/typeDefs/explorer-api.ts b/explorer/src/typeDefs/explorer-api.ts index f8350775c4..188a0c3ac0 100644 --- a/explorer/src/typeDefs/explorer-api.ts +++ b/explorer/src/typeDefs/explorer-api.ts @@ -77,8 +77,8 @@ export interface MixNodeResponseItem { status: MixnodeStatus; location: { country_name: string; - lat: number; - lng: number; + latitude?: number; + longitude?: number; three_letter_iso_country_code: string; two_letter_iso_country_code: string; }; diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index a6cd9279d7..9040441657 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-gateway" -version = "1.1.4" +version = "1.1.5" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 1fd23fa6dd..0247c29ab3 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-mixnode" -version = "1.1.4" +version = "1.1.5" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index b89227f868..2e9e91ff48 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.4" +version = "1.1.5" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-connect/CHANGELOG.md b/nym-connect/CHANGELOG.md index d6f0c7a05a..6a22e8e86d 100644 --- a/nym-connect/CHANGELOG.md +++ b/nym-connect/CHANGELOG.md @@ -1,5 +1,12 @@ ## UNRELEASED +## [nym-connect-v1.1.5](https://github.com/nymtech/nym/tree/nym-connect-v1.1.5) (2023-01-10) + +- get version number from tauri and display by @fmtabbara in https://github.com/nymtech/nym/pull/2684 +- Feature/nym connect experimental software text by @fmtabbara in https://github.com/nymtech/nym/pull/2692 +- NymConnect - Display service info in tooltip **1.1.5 Release** by @fmtabbara in https://github.com/nymtech/nym/pull/2704 +- Feat/2130 tables update rebase by @gala1234 in https://github.com/nymtech/nym/pull/2742 + ## [nym-connect-v1.1.4](https://github.com/nymtech/nym/tree/nym-connect-v1.1.4) (2022-12-20) This release contains the new opt-in Test & Earn program, and it uses a stress-tested directory of network requesters to improve reliability. It also has some bugfixes, performance improvements, and better error handling. diff --git a/nym-connect/package.json b/nym-connect/package.json index bff93c5a67..f74779b2d4 100644 --- a/nym-connect/package.json +++ b/nym-connect/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.4", + "version": "1.1.5", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index 1ef082ea8d..0d7118b97a 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.4" +version = "1.1.5" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-connect/src-tauri/tauri.conf.json b/nym-connect/src-tauri/tauri.conf.json index 05d22942c4..0e11432d04 100644 --- a/nym-connect/src-tauri/tauri.conf.json +++ b/nym-connect/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.4" + "version": "1.1.5" }, "build": { "distDir": "../dist", diff --git a/nym-connect/src/components/ConnectionStatus.tsx b/nym-connect/src/components/ConnectionStatus.tsx index c2bfcc82f0..c2f9add9ad 100644 --- a/nym-connect/src/components/ConnectionStatus.tsx +++ b/nym-connect/src/components/ConnectionStatus.tsx @@ -1,8 +1,9 @@ import React from 'react'; -import { Box, CircularProgress, Typography } from '@mui/material'; +import { Box, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material'; import { DateTime } from 'luxon'; import { ConnectionStatusKind } from '../types'; import { ServiceProvider } from '../types/directory'; +import { ServiceProviderInfo } from './ServiceProviderInfo'; const FONT_SIZE = '10px'; const FONT_WEIGHT = '600'; @@ -14,8 +15,8 @@ const ConnectionStatusContent: React.FC<{ switch (status) { case ConnectionStatusKind.connected: return ( - - Connected + + Connected to ); case ConnectionStatusKind.disconnecting: @@ -44,7 +45,7 @@ const ConnectionStatusContent: React.FC<{ ml={1} textTransform="uppercase" textAlign="center" - fontSize="10px" + fontSize={FONT_SIZE} sx={{ wordSpacing: 3, letterSpacing: 2 }} > You are not protected @@ -59,7 +60,7 @@ export const ConnectionStatus: React.FC<{ status: ConnectionStatusKind; connectedSince?: DateTime; serviceProvider?: ServiceProvider; -}> = ({ status, connectedSince, serviceProvider }) => { +}> = ({ status, serviceProvider }) => { const color = status === ConnectionStatusKind.connected || status === ConnectionStatusKind.disconnecting ? '#21D072' @@ -70,13 +71,13 @@ export const ConnectionStatus: React.FC<{ - - {serviceProvider && ( - - To {serviceProvider.description} - - )} - + {serviceProvider ? ( + }> + + {serviceProvider && {serviceProvider.description}} + + + ) : null} ); }; diff --git a/nym-connect/src/components/ServiceProviderInfo.tsx b/nym-connect/src/components/ServiceProviderInfo.tsx new file mode 100644 index 0000000000..a6289b5c41 --- /dev/null +++ b/nym-connect/src/components/ServiceProviderInfo.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Divider, Stack, Typography } from '@mui/material'; +import { ServiceProvider } from 'src/types/directory'; + +export const ServiceProviderInfo = ({ serviceProvider }: { serviceProvider: ServiceProvider }) => ( + + + Connection info + + {serviceProvider.description} + + + Gateway {serviceProvider.gateway} + + + + Provider {serviceProvider.address.slice(0, 35)}... + + +); diff --git a/nym-connect/src/context/main.tsx b/nym-connect/src/context/main.tsx index 17b627c823..3258978ff8 100644 --- a/nym-connect/src/context/main.tsx +++ b/nym-connect/src/context/main.tsx @@ -86,6 +86,8 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode .catch((e) => console.log(e)); listen('socks5-event', (e: TauriEvent) => { + console.log(e); + setError(e.payload); }).then((result) => { unlisten.push(result); diff --git a/nym-connect/src/layouts/ConnectedLayout.tsx b/nym-connect/src/layouts/ConnectedLayout.tsx index 0bf61fd4c0..9cf37b9f12 100644 --- a/nym-connect/src/layouts/ConnectedLayout.tsx +++ b/nym-connect/src/layouts/ConnectedLayout.tsx @@ -37,11 +37,13 @@ export const ConnectedLayout: React.FC<{ }) => ( <> - + - - + + + + {/* */} diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index 2e4f234db1..0dbb231f2c 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -1,6 +1,16 @@ # Changelog -## UNRELEASED +## [nym-wallet-v1.1.6](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.6) (2023-01-10) + +- wallet: rewrite some abci errors on the fly by @octol in https://github.com/nymtech/nym/pull/2716 +- Feature/node settings apy playground by @fmtabbara in https://github.com/nymtech/nym/pull/1677 +- Fix param input layout **1.1.5 Release** by @fmtabbara in https://github.com/nymtech/nym/pull/2720 +- Add epoch info to unbond modal **1.1.5 Release** by @fmtabbara in https://github.com/nymtech/nym/pull/2718 +- Feat/2130 tables update rebase by @gala1234ss as url param by @doums in https://github.com/nymtech/nym/pull/2780 + +## [nym-wallet-v1.1.5](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.5) (2022-12-22) + +This release contains the APY calculator feature. ## [nym-wallet-v1.1.5](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.5) (2022-12-22) diff --git a/nym-wallet/package.json b/nym-wallet/package.json index 21f885b496..72a440d733 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/nym-wallet-app", - "version": "1.1.5", + "version": "1.1.6", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index d554b65f83..efa20d8754 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym_wallet" -version = "1.1.5" +version = "1.1.6" description = "Nym Native Wallet" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-wallet/src-tauri/tauri.conf.json b/nym-wallet/src-tauri/tauri.conf.json index 004dd66912..722c0c1af3 100644 --- a/nym-wallet/src-tauri/tauri.conf.json +++ b/nym-wallet/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-wallet", - "version": "1.1.5" + "version": "1.1.6" }, "build": { "distDir": "../dist", diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 6ff0151b29..ae32fdefba 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Box, Button, Chip, Stack, Tooltip, Typography } from '@mui/material'; import { Link } from '@nymproject/react/link/Link'; @@ -11,6 +11,9 @@ import { Node as NodeIcon } from '../../svg-icons/node'; import { Cell, Header, NodeTable } from './NodeTable'; import { BondedMixnodeActions, TBondedMixnodeActions } from './BondedMixnodeActions'; import { NodeStats } from './NodeStats'; +import { getIntervalAsDate } from 'src/utils'; + +const textWhenNotName = 'This node has not yet set a name'; const headers: Header[] = [ { @@ -63,6 +66,7 @@ export const BondedMixnode = ({ network?: Network; onActionSelect: (action: TBondedMixnodeActions) => void; }) => { + const [nextEpoch, setNextEpoch] = useState(); const navigate = useNavigate(); const { name, @@ -78,6 +82,15 @@ export const BondedMixnode = ({ identityKey, host, } = mixnode; + + const getNextInterval = async () => { + try { + const { nextEpoch } = await getIntervalAsDate(); + setNextEpoch(nextEpoch); + } catch { + setNextEpoch(Error()); + } + }; const cells: Cell[] = [ { cell: `${stake.amount} ${stake.denom}`, @@ -121,6 +134,10 @@ export const BondedMixnode = ({ }, ]; + useEffect(() => { + getNextInterval(); + }, []); + return ( - {name && ( - - - {name} - - + {name?.includes(textWhenNotName) ? null : ( + + {name} + )} - + + + + + } Action={ - isMixnode(mixnode) && ( - - - - - - ) + + {isMixnode(mixnode) && ( + + + + + + )} + {nextEpoch instanceof Error ? null : ( + + Next epoch starts at {nextEpoch} + + )} + } > diff --git a/nym-wallet/src/components/Bonding/modals/ConfirmationModal.tsx b/nym-wallet/src/components/Bonding/modals/ConfirmationModal.tsx index 9a3c683b55..53439a8e8c 100644 --- a/nym-wallet/src/components/Bonding/modals/ConfirmationModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/ConfirmationModal.tsx @@ -14,6 +14,7 @@ export type ConfirmationDetailProps = { export const ConfirmationDetailsModal = ({ title, subtitle, + children, txUrl, status, onClose, @@ -23,6 +24,7 @@ export const ConfirmationDetailsModal = ({ onClose: () => void; sx?: SxProps; backdropProps?: object; + children?: React.ReactNode; }) => { if (status === 'error') { ; @@ -45,6 +47,7 @@ export const ConfirmationDetailsModal = ({ {title} {subtitle} + {children} {txUrl && } diff --git a/nym-wallet/src/components/Delegation/DelegationItem.tsx b/nym-wallet/src/components/Delegation/DelegationItem.tsx index d800f9f487..1b4327621c 100644 --- a/nym-wallet/src/components/Delegation/DelegationItem.tsx +++ b/nym-wallet/src/components/Delegation/DelegationItem.tsx @@ -29,15 +29,18 @@ export const DelegationItem = ({ }) => { const operatingCost = isDelegation(item) && item.cost_params?.interval_operating_cost; + const tooltipText = () => { + if (nodeIsUnbonded) { + return 'This node has unbonded and it does not exist anymore. You need to undelegate from it to get your stake and outstanding rewards (if any) back.'; + } else if (item.uses_vesting_contract_tokens) { + return 'Delegation made with locked tockens'; + } else { + return ''; + } + }; + return ( - + {nodeIsUnbonded ? ( diff --git a/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx index 798993dc49..2a9ef67f13 100644 --- a/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx @@ -18,6 +18,7 @@ import { NodeUnbondPage } from './settings-pages/NodeUnbondPage'; import { createNavItems } from './node-settings.constant'; import { isMixnode } from 'src/types'; import { ApyPlayground } from './apy-playground'; +import { getIntervalAsDate } from 'src/utils'; export const NodeSettings = () => { const theme = useTheme(); @@ -26,7 +27,7 @@ export const NodeSettings = () => { const navigate = useNavigate(); const location = useLocation(); - const [confirmationDetails, setConfirmationDetails] = useState(); + const [confirmationDetails, setConfirmationDetails] = useState(); const [value, setValue] = React.useState('General'); const handleChange = (event: React.SyntheticEvent, tab: string) => { setValue(tab); @@ -40,9 +41,11 @@ export const NodeSettings = () => { const handleUnbond = async (fee?: FeeDetails) => { const tx = await unbond(fee); + const { nextEpoch } = await getIntervalAsDate(); setConfirmationDetails({ status: 'success', title: 'Unbond successful', + subtitle: `This operation will complete when the new epoch starts at: ${nextEpoch}`, txUrl: `${urls(network).blockExplorer}/transaction/${tx?.transaction_hash}`, }); }; @@ -135,7 +138,12 @@ export const NodeSettings = () => { setConfirmationDetails(undefined); navigate('/bonding'); }} - /> + > + + You should NOT shutdown your {isMixnode(bondedNode) ? 'mix node' : 'gateway'} until the unbond process is + complete + + )} diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index 7aa7407a48..b342f32d15 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -1,24 +1,12 @@ import React, { useContext, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; -import { - Button, - Divider, - Typography, - TextField, - InputAdornment, - Grid, - CircularProgress, - Box, - FormHelperText, -} from '@mui/material'; +import { Button, Divider, Typography, TextField, InputAdornment, Grid, Box, FormHelperText } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -import { add, format, fromUnixTime } from 'date-fns'; import { isMixnode } from 'src/types'; import { - getCurrentInterval, getPendingIntervalEvents, simulateUpdateMixnodeCostParams, simulateVestingUpdateMixnodeCostParams, @@ -29,6 +17,7 @@ import { TBondedMixnode } from 'src/context/bonding'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { bondedNodeParametersValidationSchema } from 'src/components/Bonding/forms/mixnodeValidationSchema'; import { Console } from 'src/utils/console'; +import { getIntervalAsDate } from 'src/utils'; import { Alert } from 'src/components/Alert'; import { ChangeMixCostParams } from 'src/pages/bonding/types'; import { AppContext } from 'src/context'; @@ -39,7 +28,6 @@ import { LoadingModal } from 'src/components/Modals/LoadingModal'; export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const [intervalTime, setIntervalTime] = useState(); - const [nextEpoch, setNextEpoch] = useState(); const [pendingUpdates, setPendingUpdates] = useState(); const { clientDetails } = useContext(AppContext); const theme = useTheme(); @@ -63,27 +51,13 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode defaultValues, }); - const getIntervalAsDate = async () => { - const interval = await getCurrentInterval(); - const secondsToNextInterval = - Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); - - setIntervalTime( - format( - add(new Date(), { - seconds: secondsToNextInterval, - }), - 'MM/dd/yyyy HH:mm', - ), - ); - setNextEpoch( - format( - add(fromUnixTime(Number(interval.current_epoch_start_unix)), { - seconds: Number(interval.epoch_length_seconds), - }), - 'HH:mm', - ), - ); + const getCurrentInterval = async () => { + try { + const { nextInterval } = await getIntervalAsDate(); + setIntervalTime(nextInterval); + } catch { + console.log('cant retrieve next interval'); + } }; const getPendingEvents = async () => { @@ -107,7 +81,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }; useEffect(() => { - getIntervalAsDate(); + getCurrentInterval(); getPendingEvents(); }, []); @@ -137,7 +111,16 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }; return ( - + {fee && ( - - {`Next epoch ${nextEpoch}`} - {`Next interval: ${intervalTime}`} } @@ -177,7 +157,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode {isMixnode(bondedNode) && ( - + )} - + @@ -223,33 +203,31 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode Changes to cost will be applied in the next interval. - - - { - setValue('operatorCost', newValue, { shouldValidate: true, shouldDirty: true }); - }} - validationError={errors.operatorCost?.amount?.message} - denom={clientDetails?.display_mix_denom || 'nym'} - initialValue={defaultValues.operatorCost.amount} - /> - {pendingUpdates && ( - - Your last change to{' '} - - {pendingUpdates.interval_operating_cost.amount}{' '} - {pendingUpdates?.interval_operating_cost.denom.toUpperCase()}{' '} - - will be applied in the next interval - - )} - + + { + setValue('operatorCost', newValue, { shouldValidate: true, shouldDirty: true }); + }} + validationError={errors.operatorCost?.amount?.message} + denom={clientDetails?.display_mix_denom || 'nym'} + initialValue={defaultValues.operatorCost.amount} + /> + {pendingUpdates && ( + + Your last change to{' '} + + {pendingUpdates.interval_operating_cost.amount}{' '} + {pendingUpdates?.interval_operating_cost.denom.toUpperCase()}{' '} + + will be applied in the next interval + + )} - + )} {!!delegations?.length && ( - - + {nextEpoch instanceof Error ? null : ( + + Next epoch starts at {nextEpoch} + + )} )} {delegationsComponent(delegations)} diff --git a/nym-wallet/src/utils/index.ts b/nym-wallet/src/utils/index.ts index 49d56c6f72..936a89e57d 100644 --- a/nym-wallet/src/utils/index.ts +++ b/nym-wallet/src/utils/index.ts @@ -2,11 +2,20 @@ import { appWindow } from '@tauri-apps/api/window'; import bs58 from 'bs58'; import Big from 'big.js'; import { valid } from 'semver'; +import { add, format, fromUnixTime } from 'date-fns'; import { isValidRawCoin, DecCoin, MixNodeCostParams } from '@nymproject/types'; import { TPoolOption } from 'src/components'; -import { getDefaultMixnodeCostParams, getLockedCoins, getSpendableCoins, userBalance } from '../requests'; +import { + getCurrentInterval, + getDefaultMixnodeCostParams, + getLockedCoins, + getSpendableCoins, + userBalance, +} from '../requests'; import { Console } from './console'; +export * from './nextEpoch'; + export const validateKey = (key: string, bytesLength: number): boolean => { // it must be a valid base58 key try { @@ -198,3 +207,25 @@ export const unymToNym = (unym: string | Big, dp = 4) => { } return nym; }; + +export const getIntervalAsDate = async () => { + const interval = await getCurrentInterval(); + const secondsToNextInterval = + Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); + + const nextInterval = format( + add(new Date(), { + seconds: secondsToNextInterval, + }), + 'dd/MM/yyyy, HH:mm', + ); + + const nextEpoch = format( + add(fromUnixTime(Number(interval.current_epoch_start_unix)), { + seconds: Number(interval.epoch_length_seconds), + }), + 'HH:mm', + ); + + return { nextEpoch, nextInterval }; +}; diff --git a/nym-wallet/src/utils/nextEpoch.ts b/nym-wallet/src/utils/nextEpoch.ts new file mode 100644 index 0000000000..db80a22280 --- /dev/null +++ b/nym-wallet/src/utils/nextEpoch.ts @@ -0,0 +1,23 @@ +import { getCurrentInterval } from 'src/requests'; +import { add, format, fromUnixTime } from 'date-fns'; + +export const getIntervalAsDate = async () => { + const interval = await getCurrentInterval(); + const secondsToNextInterval = + Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); + + const intervalTime = format( + add(new Date(), { + seconds: secondsToNextInterval, + }), + 'dd/MM/yyyy, HH:mm', + ); + const nextEpoch = format( + add(fromUnixTime(Number(interval.current_epoch_start_unix)), { + seconds: Number(interval.epoch_length_seconds), + }), + 'HH:mm', + ); + + return { intervalTime, nextEpoch }; +}; \ No newline at end of file diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index eca04d024e..05a8ca1b3c 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.4" +version = "1.1.5" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] edition = "2021" rust-version = "1.65" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index 00b76f524e..251b1a34a9 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.4" +version = "1.1.5" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index aa73944ab8..5a26c750a0 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.4" +version = "1.1.5" authors = ["Nym Technologies SA"] edition = "2021"