From 92b9edf0dae08f878f9f70477e0e6f5c212ef102 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Tue, 4 Jul 2023 14:52:05 +0000 Subject: [PATCH 01/59] edited NC-Matrix user manual - changed setup for Mac - fixed typo --- .../dev-portal/src/tutorials/matrix.md | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/documentation/dev-portal/src/tutorials/matrix.md b/documentation/dev-portal/src/tutorials/matrix.md index 39852fed05..7351ce85ee 100644 --- a/documentation/dev-portal/src/tutorials/matrix.md +++ b/documentation/dev-portal/src/tutorials/matrix.md @@ -3,7 +3,7 @@ Chat applications became an essential part of human communication. Matrix chat has end to end encryption on protocol level and Element app users can sort their communication into spaces and rooms. Now the Matrix communities can rely on network privacy as NymConnect supports Matrix chat protocol. -Currently there is no option in Matrix's Element client to set a socks5 proxy. In order to use Element via NymConnect users have to start it from the command-line. The setup is simple, for convenience a a keyboard shortcut setting can be easily done. +Currently there is no option in Matrix's Element client to set a Socks5 proxy. In order to use Element via NymConnect users have to start it from the command-line. The setup is simple, for convenience a keyboard shortcut setting or terminal alias can be easily done. ## Setup & Run @@ -35,10 +35,46 @@ Alternatively you can add a keybinding via the CLI, using whatever config files ### Create an alias If you prefer to simply shorten the length of the command (or all your keybindings are already taken) then you can simply create an alias for this long-winded command (this example aliases that command to the single word `element`, but you can replace it with whatever you like): +**Linux** + ```sh alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" ``` -To make this alias persist, then add this to your `.bashrc` or `.zshrc` file (usually located in your `$HOME` directory) and `source` that file. +To make this alias persist, then add this to your `.bashrc` or `.zshrc` file (usually located in your `$HOME` directory) and `source` that file. This can be done by appending the alias command directly to the shell config file with one command. -Now you can run Element throught the mixnet with a single-word command. +For `bash` enter: + +```sh +alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" >> ~/.bashrc +``` + +For `zsh` enter: + +```sh +alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" >> ~/.zshrc +``` + +You can add the alias manually by opening your `$HOME` directory, enable hidden files (press `ctrl` + `h`) and open `.bashrc` or `.zshrc` file (based on your terminal setup) in a text editor, paste the string `alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080"` to the the end, save and exit. Start a new terminal and run `element`. + +**Mac** + +```sh +alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080" + +``` + +To make this alias persist, then add this to your `.zshrc` (or `.bashrc`/`.profile`) file (usually located in your `$HOME` directory) and `source` that file. This can be done by appending the alias command directly to the shell config file with one command. + +For `zsh` enter: + +```sh +alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080" >> ~/.zshrc +``` + +For `.bashrc` or `.profile` just change the end of the command. + +You can add the alias manually by opening your `$HOME` directory, enable hidden files (in Finder press `Shift` + `Command` + `.`) and open `.zshrc` file (or `.bashrc`/`.profile`) in a text editor, paste the string `alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080"` to the the end, save and exit. Start a new terminal and run `element`. + + +**Now you can run Element through the Nym Mixnet with a single-word command.** From 37c875d8ee6b807f0c5b1d1020dbaa6c4ecf4a45 Mon Sep 17 00:00:00 2001 From: Pierre Dommerc Date: Mon, 10 Jul 2023 13:18:46 +0200 Subject: [PATCH 02/59] build(nym-connect-desktop): speedy mode (#3636) --- .../workflows/nym-connect-s-publish-macos.yml | 104 ++++++++++++++++++ .../nym-connect-s-publish-ubuntu.yml | 79 +++++++++++++ .../nym-connect-s-publish-windows10.yml | 98 +++++++++++++++++ .../desktop/scripts/pre_medium_build.sh | 17 +++ nym-connect/desktop/src-tauri/src/build.rs | 7 ++ nym-connect/desktop/src-tauri/src/main.rs | 6 +- .../src/operations/connection/status.rs | 7 +- .../src-tauri/src/operations/directory/mod.rs | 11 +- nym-connect/desktop/src-tauri/src/state.rs | 4 + .../src/components/ConnectionStatus.tsx | 30 +++-- nym-connect/desktop/src/context/main.tsx | 17 ++- .../desktop/src/context/mocks/main.tsx | 1 + nym-connect/desktop/src/types/common.ts | 1 + nym-connect/desktop/src/types/index.ts | 1 + 14 files changed, 365 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/nym-connect-s-publish-macos.yml create mode 100644 .github/workflows/nym-connect-s-publish-ubuntu.yml create mode 100644 .github/workflows/nym-connect-s-publish-windows10.yml create mode 100755 nym-connect/desktop/scripts/pre_medium_build.sh create mode 100644 nym-connect/desktop/src/types/common.ts diff --git a/.github/workflows/nym-connect-s-publish-macos.yml b/.github/workflows/nym-connect-s-publish-macos.yml new file mode 100644 index 0000000000..a2f04b881c --- /dev/null +++ b/.github/workflows/nym-connect-s-publish-macos.yml @@ -0,0 +1,104 @@ +name: Publish Nym Connect - desktop (MacOS) +on: + workflow_dispatch: + inputs: + release_tag: + required: true + description: Release tag (nym-connect-s-v*) + type: string + default: 'nym-connect-s-v1.0.0' + push: + tags: + - nym-connect-s-v* + +defaults: + run: + working-directory: nym-connect/desktop + +jobs: + publish-tauri: + if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} + strategy: + fail-fast: false + matrix: + platform: [macos-latest] + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v2 + + - name: Node v16 + uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Install the Apple developer certificate for code signing + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + + # import certificate and provisioning profile from secrets + echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH + + # create temporary keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH + + - name: Create env file + uses: timheuer/base64-to-file@v1.1 + with: + fileName: '.env' + encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} + + - name: Prepare for build + env: + RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} + run: ./scripts/pre_medium_build.sh + + - name: Install app dependencies and build it + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + NYM_CONNECT_ENABLE_MEDIUM: 1 + run: yarn && yarn build + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: nym-connect-s_1.0.0_x64.dmg + path: nym-connect/desktop/target/release/bundle/dmg/nym-connect-s_1.0.0_x64.dmg + retention-days: 30 + + - name: Clean up keychain + if: ${{ always() }} + run: | + security delete-keychain $RUNNER_TEMP/app-signing.keychain-db + + - id: create-release + name: Upload to release based on tag name + uses: softprops/action-gh-release@v1 + if: github.event_name == 'release' + with: + files: | + nym-connect/desktop/target/release/bundle/dmg/*.dmg + nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz* diff --git a/.github/workflows/nym-connect-s-publish-ubuntu.yml b/.github/workflows/nym-connect-s-publish-ubuntu.yml new file mode 100644 index 0000000000..10c461aca6 --- /dev/null +++ b/.github/workflows/nym-connect-s-publish-ubuntu.yml @@ -0,0 +1,79 @@ +name: Publish NymConnect S - desktop (Ubuntu) +on: + workflow_dispatch: + inputs: + release_tag: + required: true + description: Release tag (nym-connect-s-v*) + type: string + default: 'nym-connect-s-v1.0.0' + push: + tags: + - nym-connect-s-v* + +defaults: + run: + working-directory: nym-connect/desktop + +jobs: + publish-tauri: + if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} + strategy: + fail-fast: false + matrix: + platform: [custom-runner-linux] + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v2 + + - name: Tauri dependencies + run: > + sudo apt-get update && + sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev + continue-on-error: true + + - name: Node v16 + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Install app dependencies + run: yarn + - name: Create env file + uses: timheuer/base64-to-file@v1.1 + with: + fileName: '.env' + encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} + + - name: Prepare for build + env: + RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} + run: ./scripts/pre_medium_build.sh + + - name: Build app + env: + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + NYM_CONNECT_ENABLE_MEDIUM: 1 + run: yarn build + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: nym-connect-s.AppImage.tar.gz + path: nym-connect/desktop/target/release/bundle/appimage/nym-connect-s_1.0.0_amd64.AppImage + retention-days: 30 + + - id: create-release + name: Upload to release based on tag name + uses: softprops/action-gh-release@v1 + if: github.event_name == 'release' + with: + files: | + nym-connect/desktop/target/release/bundle/appimage/*.AppImage + nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz* diff --git a/.github/workflows/nym-connect-s-publish-windows10.yml b/.github/workflows/nym-connect-s-publish-windows10.yml new file mode 100644 index 0000000000..efdfa40b27 --- /dev/null +++ b/.github/workflows/nym-connect-s-publish-windows10.yml @@ -0,0 +1,98 @@ +name: Publish Nym Connect - desktop (Windows 10) +on: + workflow_dispatch: + inputs: + release_tag: + required: true + description: Release tag (nym-connect-s-v*) + type: string + default: 'nym-connect-s-v1.0.0' + push: + tags: + - nym-connect-s-v* + +defaults: + run: + working-directory: nym-connect/desktop + +jobs: + publish-tauri: + if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} + strategy: + fail-fast: false + matrix: + platform: [windows10] + runs-on: ${{ matrix.platform }} + + steps: + - name: Clean up first + continue-on-error: true + working-directory: . + run: | + cd .. + del /s /q /A:H nym + rmdir /s /q nym + + - uses: actions/checkout@v3 + + - name: Import signing certificate + env: + WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} + WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + run: | + New-Item -ItemType directory -Path certificate + Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE + certutil -decode certificate/tempCert.txt certificate/certificate.pfx + Remove-Item -path certificate -include tempCert.txt + Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText) + + - name: Node v16 + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Create env file + uses: timheuer/base64-to-file@v1.1 + with: + fileName: '.env' + encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} + + - name: Install app dependencies + run: yarn --network-timeout 100000 + + - name: Prepare for build + env: + RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} + run: ./scripts/pre_medium_build.sh + + - name: Build and sign it + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }} + WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} + WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + NYM_CONNECT_ENABLE_MEDIUM: 1 + run: yarn build + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: nym-connect-s_1.0.0_x64_en-US.msi + path: nym-connect/desktop/target/release/bundle/msi/nym-connect-s_1.0.0_x64_en-US.msi + retention-days: 30 + + - id: create-release + name: Upload to release based on tag name + uses: softprops/action-gh-release@v1 + if: github.event_name == 'release' + with: + files: | + nym-connect/desktop/target/release/bundle/msi/*.msi + nym-connect/desktop/target/release/bundle/msi/*.msi.zip* diff --git a/nym-connect/desktop/scripts/pre_medium_build.sh b/nym-connect/desktop/scripts/pre_medium_build.sh new file mode 100755 index 0000000000..5a797ffc8f --- /dev/null +++ b/nym-connect/desktop/scripts/pre_medium_build.sh @@ -0,0 +1,17 @@ +#! /bin/bash + +set -e + +if ! [[ "$RELEASE_TAG" =~ ^nym-connect-s-v.*? ]]; then + echo -e " ✗ Invalid release tag $RELEASE_TAG" + exit 1 +fi + +version="${RELEASE_TAG#nym-connect-s-v}" + +sed -i "s/^name = \".*\"/name = \"nym-connect-s\"/" src-tauri/Cargo.toml +sed -i "s/^version = \".*\"/version = \"$version\"/" src-tauri/Cargo.toml +sed -i 's/"productName": "nym-connect"/"productName": "NymConnect S"/' src-tauri/tauri.conf.json +sed -i "s/\"version\": \".*\"/\"version\": \"$version\"/" src-tauri/tauri.conf.json + +echo -e " ✓ bump version $version" diff --git a/nym-connect/desktop/src-tauri/src/build.rs b/nym-connect/desktop/src-tauri/src/build.rs index 261851f6b6..2c8232a54b 100644 --- a/nym-connect/desktop/src-tauri/src/build.rs +++ b/nym-connect/desktop/src-tauri/src/build.rs @@ -1,3 +1,10 @@ +use std::env; + fn main() { + if env::var_os("NYM_CONNECT_ENABLE_MEDIUM").is_some() { + println!("cargo:rustc-cfg=medium_enabled"); + } + println!("cargo:rerun-if-changed=build.rs"); + tauri_build::build(); } diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index fc51403ab2..f41f401812 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -10,7 +10,7 @@ use tauri::Manager; use tokio::sync::RwLock; use crate::menu::{create_tray_menu, tray_menu_event_handler}; -use crate::state::State; +use crate::state::{is_medium_enabled, State}; use crate::window::window_toggle; mod config; @@ -25,7 +25,8 @@ mod tasks; mod window; fn main() { - if std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() { + if is_medium_enabled() { + println!("medium mode enabled"); std::env::set_var("NYM_CONNECT_DISABLE_COVER", "1"); std::env::set_var("NYM_CONNECT_ENABLE_MIXED_SIZE_PACKETS", "1"); std::env::set_var("NYM_CONNECT_DISABLE_PER_HOP_DELAYS", "1"); @@ -56,6 +57,7 @@ fn main() { crate::operations::connection::status::get_connection_status, crate::operations::connection::status::get_gateway_connection_status, crate::operations::connection::status::start_connection_health_check_task, + crate::operations::connection::status::is_medium_mode_enabled, crate::operations::directory::get_services, crate::operations::directory::get_gateways_detailed, crate::operations::export::export_keys, diff --git a/nym-connect/desktop/src-tauri/src/operations/connection/status.rs b/nym-connect/desktop/src-tauri/src/operations/connection/status.rs index 7710524fb5..8391f724cf 100644 --- a/nym-connect/desktop/src-tauri/src/operations/connection/status.rs +++ b/nym-connect/desktop/src-tauri/src/operations/connection/status.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use tokio::sync::RwLock; use crate::models::{ConnectionStatusKind, ConnectivityTestResult, GatewayConnectionStatusKind}; -use crate::state::State; +use crate::state::{is_medium_enabled, State}; #[tauri::command] pub async fn get_connection_status( @@ -42,3 +42,8 @@ pub fn start_connection_health_check_task( ) { tasks::start_connection_check(state.inner().clone(), window); } + +#[tauri::command] +pub async fn is_medium_mode_enabled(_state: tauri::State<'_, Arc>>) -> Result { + Ok(is_medium_enabled()) +} diff --git a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs index 6195d41283..77bd2b8e84 100644 --- a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs +++ b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs @@ -4,6 +4,7 @@ use crate::error::Result; use crate::models::{ DirectoryService, DirectoryServiceProvider, HarbourMasterService, PagedResult, }; +use crate::state::is_medium_enabled; use nym_api_requests::models::GatewayBondAnnotated; use nym_contracts_common::types::Percent; @@ -20,10 +21,10 @@ static GATEWAYS_DETAILED_URL: &str = "https://validator.nymtech.net/api/v1/status/gateways/detailed"; fn get_services_url() -> &'static str { - std::env::var("NYM_CONNECT_ENABLE_MEDIUM") - .is_ok() - .then(|| SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM) - .unwrap_or(SERVICE_PROVIDER_WELLKNOWN_URL) + if is_medium_enabled() { + return SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM; + } + SERVICE_PROVIDER_WELLKNOWN_URL } #[tauri::command] @@ -33,7 +34,7 @@ pub async fn get_services() -> Result> { log::trace!("Received: {:#?}", all_services); // Early return if we're running with medium toggle enabled - if std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() { + if is_medium_enabled() { return Ok(all_services.into_iter().flat_map(|sp| sp.items).collect()); } diff --git a/nym-connect/desktop/src-tauri/src/state.rs b/nym-connect/desktop/src-tauri/src/state.rs index 9e4ba9c10b..b44ca16107 100644 --- a/nym-connect/desktop/src-tauri/src/state.rs +++ b/nym-connect/desktop/src-tauri/src/state.rs @@ -244,3 +244,7 @@ impl State { self.set_state(ConnectionStatusKind::Disconnected, window); } } + +pub fn is_medium_enabled() -> bool { + cfg!(medium_enabled) || std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() +} diff --git a/nym-connect/desktop/src/components/ConnectionStatus.tsx b/nym-connect/desktop/src/components/ConnectionStatus.tsx index 0c02ff2585..c23abdb7d8 100644 --- a/nym-connect/desktop/src/components/ConnectionStatus.tsx +++ b/nym-connect/desktop/src/components/ConnectionStatus.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import { Box, CircularProgress, Tooltip, Typography } from '@mui/material'; +import { Box, CircularProgress, Stack, Tooltip, Typography } from '@mui/material'; import { DateTime } from 'luxon'; import { ErrorOutline, InfoOutlined } from '@mui/icons-material'; import { ConnectionStatusKind, GatewayPerformance } from '../types'; import { ServiceProvider } from '../types/directory'; import { GatwayWarningInfo, ServiceProviderInfo } from './TooltipInfo'; +import { useClientContext } from '../context/main'; const FONT_SIZE = '14px'; const FONT_WEIGHT = '600'; @@ -15,6 +16,8 @@ const ConnectionStatusContent: FCWithChildren<{ serviceProvider?: ServiceProvider; gatewayError: boolean; }> = ({ status, serviceProvider, gatewayError }) => { + const { speedMode } = useClientContext(); + if (gatewayError) { return ( : undefined}> @@ -37,14 +40,23 @@ const ConnectionStatusContent: FCWithChildren<{ switch (status) { case 'connected': return ( - : undefined}> - - - - Connected to Nym Mixnet - - - + <> + : undefined}> + + + + Connected to Nym Mixnet + + + + {speedMode === 'medium' && ( + + + Speedy mode activated + + + )} + ); case 'disconnected': return ( diff --git a/nym-connect/desktop/src/context/main.tsx b/nym-connect/desktop/src/context/main.tsx index f1dbe5948a..462c425800 100644 --- a/nym-connect/desktop/src/context/main.tsx +++ b/nym-connect/desktop/src/context/main.tsx @@ -6,7 +6,7 @@ import { getVersion } from '@tauri-apps/api/app'; import { useEvents } from 'src/hooks/events'; import { UserDefinedGateway, UserDefinedSPAddress } from 'src/types/service-provider'; import { getItemFromStorage, setItemInStorage } from 'src/utils'; -import { ConnectionStatusKind, GatewayPerformance } from '../types'; +import { ConnectionStatusKind, GatewayPerformance, SpeedMode } from '../types'; import { ConnectionStatsItem } from '../components/ConnectionStats'; import { ServiceProvider } from '../types/directory'; import initSentry from '../sentry'; @@ -43,6 +43,7 @@ export type TClientContext = { setUserDefinedGateway: React.Dispatch>; setUserDefinedSPAddress: React.Dispatch>; setMonitoring: (value: boolean) => Promise; + speedMode: SpeedMode; }; export const ClientContext = createContext({} as TClientContext); @@ -67,6 +68,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { address: undefined, }); const [monitoringEnabled, setMonitoringEnabled] = useState(false); + const [speedMode, setspeedMode] = useState('slow'); const getAppVersion = async () => { const version = await getVersion(); @@ -85,6 +87,17 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { initSentryClient(); }, []); + useEffect(() => { + const initSpeedMode = async () => { + const isEnabled = await invoke('is_medium_mode_enabled'); + if (isEnabled) { + setspeedMode('medium'); + } + }; + + initSpeedMode(); + }, []); + useEffect(() => { setItemInStorage({ key: FORAGE_GATEWAY_KEY, value: userDefinedGateway }); }, [userDefinedGateway]); @@ -215,6 +228,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { setUserDefinedGateway, setUserDefinedSPAddress, setMonitoring, + speedMode, }), [ mode, @@ -231,6 +245,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { userDefinedGateway, userDefinedSPAddress, monitoringEnabled, + speedMode, ], ); diff --git a/nym-connect/desktop/src/context/mocks/main.tsx b/nym-connect/desktop/src/context/mocks/main.tsx index 8c602596eb..9ae5495ac8 100644 --- a/nym-connect/desktop/src/context/mocks/main.tsx +++ b/nym-connect/desktop/src/context/mocks/main.tsx @@ -12,6 +12,7 @@ const mockValues: TClientContext = { userDefinedGateway: { isActive: false, gateway: '' }, userDefinedSPAddress: { isActive: false, address: '' }, monitoringEnabled: false, + speedMode: 'slow', setShowInfoModal: () => {}, setMode: () => {}, clearError: () => {}, diff --git a/nym-connect/desktop/src/types/common.ts b/nym-connect/desktop/src/types/common.ts new file mode 100644 index 0000000000..d4895499d5 --- /dev/null +++ b/nym-connect/desktop/src/types/common.ts @@ -0,0 +1 @@ +export type SpeedMode = 'fast' | 'medium' | 'slow'; diff --git a/nym-connect/desktop/src/types/index.ts b/nym-connect/desktop/src/types/index.ts index 6bc150d410..f8ea4fd95f 100644 --- a/nym-connect/desktop/src/types/index.ts +++ b/nym-connect/desktop/src/types/index.ts @@ -1,2 +1,3 @@ export * from './rust'; export * from './connection'; +export * from './common'; From c99309dd79762f41908d504c9a5de92954d9e34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Mon, 10 Jul 2023 15:14:16 +0300 Subject: [PATCH 03/59] Use NYXD env in api (#3654) --- nym-api/src/support/cli/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nym-api/src/support/cli/mod.rs b/nym-api/src/support/cli/mod.rs index facbc6c7ff..1bcc518ad4 100644 --- a/nym-api/src/support/cli/mod.rs +++ b/nym-api/src/support/cli/mod.rs @@ -9,6 +9,7 @@ use anyhow::Result; use clap::Parser; use lazy_static::lazy_static; use nym_bin_common::build_information::BinaryBuildInformation; +use nym_config::defaults::var_names::NYXD; use nym_config::OptionalSet; use nym_validator_client::nyxd; @@ -109,7 +110,11 @@ pub(crate) struct CliArgs { pub(crate) fn override_config(config: Config, args: CliArgs) -> Config { config - .with_optional(Config::with_custom_nyxd_validator, args.nyxd_validator) + .with_optional_env( + Config::with_custom_nyxd_validator, + args.nyxd_validator, + NYXD, + ) .with_optional_env( Config::with_custom_mixnet_contract, args.mixnet_contract, From 6e2eaf29e74b557ce81c90ac5db0229d91d5bbcc Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Tue, 4 Jul 2023 14:52:05 +0000 Subject: [PATCH 04/59] edited NC-Matrix user manual - changed setup for Mac - fixed typo --- .../dev-portal/src/tutorials/matrix.md | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/documentation/dev-portal/src/tutorials/matrix.md b/documentation/dev-portal/src/tutorials/matrix.md index 39852fed05..7351ce85ee 100644 --- a/documentation/dev-portal/src/tutorials/matrix.md +++ b/documentation/dev-portal/src/tutorials/matrix.md @@ -3,7 +3,7 @@ Chat applications became an essential part of human communication. Matrix chat has end to end encryption on protocol level and Element app users can sort their communication into spaces and rooms. Now the Matrix communities can rely on network privacy as NymConnect supports Matrix chat protocol. -Currently there is no option in Matrix's Element client to set a socks5 proxy. In order to use Element via NymConnect users have to start it from the command-line. The setup is simple, for convenience a a keyboard shortcut setting can be easily done. +Currently there is no option in Matrix's Element client to set a Socks5 proxy. In order to use Element via NymConnect users have to start it from the command-line. The setup is simple, for convenience a keyboard shortcut setting or terminal alias can be easily done. ## Setup & Run @@ -35,10 +35,46 @@ Alternatively you can add a keybinding via the CLI, using whatever config files ### Create an alias If you prefer to simply shorten the length of the command (or all your keybindings are already taken) then you can simply create an alias for this long-winded command (this example aliases that command to the single word `element`, but you can replace it with whatever you like): +**Linux** + ```sh alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" ``` -To make this alias persist, then add this to your `.bashrc` or `.zshrc` file (usually located in your `$HOME` directory) and `source` that file. +To make this alias persist, then add this to your `.bashrc` or `.zshrc` file (usually located in your `$HOME` directory) and `source` that file. This can be done by appending the alias command directly to the shell config file with one command. -Now you can run Element throught the mixnet with a single-word command. +For `bash` enter: + +```sh +alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" >> ~/.bashrc +``` + +For `zsh` enter: + +```sh +alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080" >> ~/.zshrc +``` + +You can add the alias manually by opening your `$HOME` directory, enable hidden files (press `ctrl` + `h`) and open `.bashrc` or `.zshrc` file (based on your terminal setup) in a text editor, paste the string `alias element="element-desktop --proxy-server=socks5://127.0.0.1:1080"` to the the end, save and exit. Start a new terminal and run `element`. + +**Mac** + +```sh +alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080" + +``` + +To make this alias persist, then add this to your `.zshrc` (or `.bashrc`/`.profile`) file (usually located in your `$HOME` directory) and `source` that file. This can be done by appending the alias command directly to the shell config file with one command. + +For `zsh` enter: + +```sh +alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080" >> ~/.zshrc +``` + +For `.bashrc` or `.profile` just change the end of the command. + +You can add the alias manually by opening your `$HOME` directory, enable hidden files (in Finder press `Shift` + `Command` + `.`) and open `.zshrc` file (or `.bashrc`/`.profile`) in a text editor, paste the string `alias element="open -a Element --args --proxy-server=socks5://127.0.0.1:1080"` to the the end, save and exit. Start a new terminal and run `element`. + + +**Now you can run Element through the Nym Mixnet with a single-word command.** From 766261f7748f2b2faa48a37fe480c3c8bbc3f808 Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 11 Jul 2023 09:56:54 +0200 Subject: [PATCH 05/59] sync gh actions for s with normal ones --- .github/workflows/nym-connect-s-publish-macos.yml | 6 +++--- .github/workflows/nym-connect-s-publish-ubuntu.yml | 14 ++++++++++---- .../workflows/nym-connect-s-publish-windows10.yml | 12 +++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/nym-connect-s-publish-macos.yml b/.github/workflows/nym-connect-s-publish-macos.yml index a2f04b881c..d4b50860d6 100644 --- a/.github/workflows/nym-connect-s-publish-macos.yml +++ b/.github/workflows/nym-connect-s-publish-macos.yml @@ -27,7 +27,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Node v16 + - name: Node uses: actions/setup-node@v3 with: node-version: 18 @@ -58,7 +58,7 @@ jobs: security list-keychain -d user -s $KEYCHAIN_PATH - name: Create env file - uses: timheuer/base64-to-file@v1.1 + uses: timheuer/base64-to-file@v1.2 with: fileName: '.env' encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} @@ -86,7 +86,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: nym-connect-s_1.0.0_x64.dmg - path: nym-connect/desktop/target/release/bundle/dmg/nym-connect-s_1.0.0_x64.dmg + path: nym-connect/desktop/target/release/bundle/dmg/nym-connect-s_1*_x64.dmg retention-days: 30 - name: Clean up keychain diff --git a/.github/workflows/nym-connect-s-publish-ubuntu.yml b/.github/workflows/nym-connect-s-publish-ubuntu.yml index 10c461aca6..204a59a87b 100644 --- a/.github/workflows/nym-connect-s-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-s-publish-ubuntu.yml @@ -33,7 +33,7 @@ jobs: sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev continue-on-error: true - - name: Node v16 + - name: Node uses: actions/setup-node@v3 with: node-version: 18 @@ -42,10 +42,16 @@ jobs: uses: actions-rs/toolchain@v1 with: toolchain: stable + + - name: Install project dependencies + shell: bash + run: cd .. && yarn --network-timeout 100000 + - name: Install app dependencies run: yarn + - name: Create env file - uses: timheuer/base64-to-file@v1.1 + uses: timheuer/base64-to-file@v1.2 with: fileName: '.env' encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} @@ -56,17 +62,17 @@ jobs: run: ./scripts/pre_medium_build.sh - name: Build app + run: yarn build env: TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} NYM_CONNECT_ENABLE_MEDIUM: 1 - run: yarn build - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: nym-connect-s.AppImage.tar.gz - path: nym-connect/desktop/target/release/bundle/appimage/nym-connect-s_1.0.0_amd64.AppImage + path: nym-connect/desktop/target/release/bundle/appimage/nym-connect-s_1*_amd64.AppImage retention-days: 30 - id: create-release diff --git a/.github/workflows/nym-connect-s-publish-windows10.yml b/.github/workflows/nym-connect-s-publish-windows10.yml index efdfa40b27..06d0847b95 100644 --- a/.github/workflows/nym-connect-s-publish-windows10.yml +++ b/.github/workflows/nym-connect-s-publish-windows10.yml @@ -46,7 +46,7 @@ jobs: Remove-Item -path certificate -include tempCert.txt Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText) - - name: Node v16 + - name: Node uses: actions/setup-node@v3 with: node-version: 18 @@ -57,12 +57,17 @@ jobs: toolchain: stable - name: Create env file - uses: timheuer/base64-to-file@v1.1 + uses: timheuer/base64-to-file@v1.2 with: fileName: '.env' encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} + - name: Install project dependencies + shell: bash + run: cd .. && yarn --network-timeout 100000 + - name: Install app dependencies + shell: bash run: yarn --network-timeout 100000 - name: Prepare for build @@ -71,6 +76,7 @@ jobs: run: ./scripts/pre_medium_build.sh - name: Build and sign it + shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }} @@ -85,7 +91,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: nym-connect-s_1.0.0_x64_en-US.msi - path: nym-connect/desktop/target/release/bundle/msi/nym-connect-s_1.0.0_x64_en-US.msi + path: nym-connect/desktop/target/release/bundle/msi/nym-connect-s_1*_x64_en-US.msi retention-days: 30 - id: create-release From 34de42fe7a1f08a8ab56c0c12b56ce5d66cae20c Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 11 Jul 2023 15:51:02 +0200 Subject: [PATCH 06/59] updated validator docs: upgrade to 0.32.0 instructions --- documentation/docs/src/nodes/validator-setup.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/documentation/docs/src/nodes/validator-setup.md b/documentation/docs/src/nodes/validator-setup.md index 153622740b..053a19253d 100644 --- a/documentation/docs/src/nodes/validator-setup.md +++ b/documentation/docs/src/nodes/validator-setup.md @@ -593,18 +593,19 @@ nyxd tx slashing unjail ### Upgrading your validator -Upgrading from `v0.26.0` -> `v0.31.1` process is fairly simple. Grab the v0.31.1 release tarball from the [`nyxd` releases page](https://github.com/nymtech/nyxd/releases), and untar it. Inside are two files: +Upgrading from `v0.31.1` -> `v0.32.0` process is fairly simple. Grab the `v0.32.0` release tarball from the [`nyxd` releases page](https://github.com/nymtech/nyxd/releases), and untar it. Inside are two files: -- the new validator (`nyxd`) v0.31.1 +- the new validator (`nyxd`) v0.32.0 - the new wasmvm (it depends on your platform, but most common filename is `libwasmvm.x86_64.so`) -Before the upgrade height, copy `libwasmvm.x86_64.so` to the default LD_LIBRARY_PATH on your system (on Ubuntu 20.04 this is `/lib/x86_64-linux-gnu/`): +Wait for the upgrade height to be reached and the chain to halt awaiting upgrade, then: -Then just swap in your new `nyxd` binary and restart once the halt height is reached. +* copy `libwasmvm.x86_64.so` to the default LD_LIBRARY_PATH on your system (on Ubuntu 20.04 this is `/lib/x86_64-linux-gnu/`) replacing your existing file with the same name. +* swap in your new `nyxd` binary and restart. -You can also use something like [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor) - grab the relevant information from the current upgrade proposal [here](https://nym.explorers.guru/proposal/8). +You can also use something like [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor) - grab the relevant information from the current upgrade proposal [here](https://nym.explorers.guru/proposal/9). -Note: Cosmovisor will swap the `nyxd` binary, but you'll need to already have the `libwasmvm.x86_64.so` in place. Luckily, the name of the wasmvm in v0.26.1 was `libwasmvm.so`, and the new name is `libwasmvm.x86_64.so`, so you can have it already sitting there without disrupting service. +Note: Cosmovisor will swap the `nyxd` binary, but you'll need to already have the `libwasmvm.x86_64.so` in place. #### Common reasons for your validator being jailed From a98613d83c38c31e90c5c618f9b57c7287e568c1 Mon Sep 17 00:00:00 2001 From: Lorexia Date: Tue, 11 Jul 2023 19:57:21 +0200 Subject: [PATCH 07/59] Update community application list, merge community and guides pages, update SUMMARY file, update overview file --- documentation/dev-portal/src/SUMMARY.md | 3 +- ...d => community-applications-and-guides.md} | 45 ++++++++++++++ .../community-resources/community-guides.md | 17 ------ .../profile_picture/darkfi_over_nym_pp.webp | Bin 0 -> 1736 bytes .../profile_picture/nym_dashboard_pp.svg | 57 ++++++++++++++++++ .../dev-portal/src/quickstart/overview.md | 3 +- 6 files changed, 104 insertions(+), 21 deletions(-) rename documentation/dev-portal/src/community-resources/{community-applications.md => community-applications-and-guides.md} (50%) create mode 100644 documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.webp create mode 100644 documentation/dev-portal/src/images/profile_picture/nym_dashboard_pp.svg diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index be35e9c30a..aeae804662 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -40,8 +40,7 @@ # Community Resources - [Nym DevRel AMAs](community-resources/ama.md) -- [Community Applications](community-resources/community-applications.md) -- [Community Guides](community-resources/community-guides.md) +- [Community Applications and Guides](community-resources/community-applications-and-guides.md) - [Change Service Grantee Information](info-request.md) - [Rewards FAQ](community-resources/rewards-faq.md) --- diff --git a/documentation/dev-portal/src/community-resources/community-applications.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md similarity index 50% rename from documentation/dev-portal/src/community-resources/community-applications.md rename to documentation/dev-portal/src/community-resources/community-applications-and-guides.md index 9eada01337..ceff0e2291 100644 --- a/documentation/dev-portal/src/community-resources/community-applications.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -55,7 +55,52 @@ We love seeing our developer community create applications using Nym. If you wou + +## Nym Dashboard + +> Developed by No Trust Verify, this dashboard is a great tool to get information about the mixnet, gateways and mixnodes. +* [Deployed Website App](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) + + + + + +## IsNymUp + +> A tool that helps check the heath of the Nym network as well as some mixnet related statistics. +* [Deployed Website App](https://isnymup.com/) + + + + + + +## DarkFi over Nym + +> In this example, DarkFi used Nym's Mixnet to allow users to anonymously connect to other peers in the Darkfi network. +* [Github](https://github.com/darkrenaissance/darkfi) +* [Documentation](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html) + + +# Community Guides + +We aren't the only ones writing documentation: the Nym developer community is also a great source of guides and resources, some of which we've included here. + +## No Trust Verify + +>No Trust Verify is a project that aims to build open-source, privacy-enhancing technologies that make it easier to use the Internet securely and anonymously. Their focus is on providing tools and services that make it simple for developers to create decentralized applications (dApps) that respect users' privacy. + +* [Awesome Nym list](https://notrustverify.github.io/awesome-nym/) ([GitHub](https://github.com/notrustverify/awesome-nym)) +* A lot of guides can be found on the [NTV Blog](https://blog.notrustverify.ch/) + +## The Way of the NYMJA + +by Pineapple Proxy🍍 + +>Born out of a study group from Nym's Shipyard Academy, Pineapple Proxy has emerged as a cluster of motivated and skilled individuals who see the new internet taking shape. With vibecare at the heart of their approach, this zesty collective is on a mission to make privacy convenient for everyone via content, new tools, events, and novel experiences. They believe in collective intelligence, empathy, and collaboration as the means by which privacy will become a meaningful reality. +* [Website](https://pnproxy.org/welcome.html) ([GitHub](https://github.com/Pineapple-Proxy-DAO/web)) + diff --git a/documentation/dev-portal/src/community-resources/community-guides.md b/documentation/dev-portal/src/community-resources/community-guides.md index 7a5973f6f2..e69de29bb2 100644 --- a/documentation/dev-portal/src/community-resources/community-guides.md +++ b/documentation/dev-portal/src/community-resources/community-guides.md @@ -1,17 +0,0 @@ -# Community Guides - -We aren't the only ones writing documentation: the Nym developer community is also a great source of guides and resources, some of which we've included here. - -## No Trust Verify - ->No Trust Verify is a project that aims to build open-source, privacy-enhancing technologies that make it easier to use the Internet securely and anonymously. Their focus is on providing tools and services that make it simple for developers to create decentralized applications (dApps) that respect users' privacy. - -* [Awesome Nym list](https://notrustverify.github.io/awesome-nym/) ([GitHub](https://github.com/notrustverify/awesome-nym)) -* A lot of guides can be found on the [NTV Blog](https://blog.notrustverify.ch/) - -## The Way of the NYMJA - -by Pineapple Proxy🍍 - ->Born out of a study group from Nym's Shipyard Academy, Pineapple Proxy has emerged as a cluster of motivated and skilled individuals who see the new internet taking shape. With vibecare at the heart of their approach, this zesty collective is on a mission to make privacy convenient for everyone via content, new tools, events, and novel experiences. They believe in collective intelligence, empathy, and collaboration as the means by which privacy will become a meaningful reality. -* [Website](https://pnproxy.org/welcome.html) ([GitHub](https://github.com/Pineapple-Proxy-DAO/web)) diff --git a/documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.webp b/documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.webp new file mode 100644 index 0000000000000000000000000000000000000000..e181cf922da0149696d5d6d7ca4efce140aa676c GIT binary patch literal 1736 zcmbu7dpML?9LJAwDMM5!7Q5OJ%ThGCk7V30p~;9rm|;vBOf!UHTMAQ+8kbqosxU(g zEpiDxOA!%WFih=(E~KP(lUx?fp5b}&NBitQd*1h)^LfAL_dDnOzR!zuadd2z0pOqm z*2~As+!qM|(1N{e<#n;M^I{|5CqS^Nq)3L85de`amFLAw_r}@5+T!CK!Ldi zP>lr)5C&&5)WhIIg%Pl=dB5fIf}_9tA4}1#ruQeAppEj0N~yWKwdroI`BNj0Qjf6Bc%Y?S+-Xn9K3opL)#?w zHMnAHtL_pp`AA~VsT9+!fq_CqV%mZtm>0$U*)V53;Vqa-svWEw%u~ZlTQq#q$r|e@ z*qFPkgk?-*siHcVg=WOpU0a$fosyd+s+3? zSj3Ii&$#-fch$6e=w+WP!R)YE3X!G$7Jnz_kVW?Ww4OTs5lr;GC*QnLs4*k);u zev1G2z~k>9yg!VvOgOS3GS!35?e~Y@Mx92Et3x&#(kwb*O@MZ5ix39KVUTm?6=(3)-diBQa znp=7!FQ)UFk(z+Vr##eXzE$ebTxFo9!p%coPfsh@*CI~|TJ9FKmm6jT_6@lSYZoIg z?MAp&Ap3Yd>?|wk2RZUR64m-{r1W;HY4QvOPZqe}LpMe%`f)rR!}Mk-c0V_e&SR2P z!}vaaY`Ui<>EdF&L2s2qvU+miMfOn>n})XMQv;dC+}eV_at_{fywJvWTXvYOzU(-H zdQ0pm*VYU>WZl@anMOCLsQk!kDAa4h1@y|W=EG6rvPOIzGjyjF&h?1w=z$aua_Fpy zpOcI#MggI8I!=$LaL$TejPm!hycR;=Uo+{-+wtIArfjuiZrk)U=8Rs!IB5f6x>Tj2 zTs9$)(yp<|P_Afn;Hh?T`R=n@!{ieCwuxqsJtA-7m*>=^bxO*Iw`Cen$H#lVIf8ak zs};uFHeWJ5->TC-#>7@M;c|2YW4@M>QEu6rnF4#)prr%r+fGdhw)hx}NEdd>ybxMz zG~!#l^!g@IFF`LlxQo)N*hrYu#bUXoG86l6)%)ZYCCW6smqTE*=elgz`y7W)b6b5Z z>*F*>ohRO*?e_q~?&v+on;SFH9xmMqKOS~9qTJUsOKGn#oqE=aI!;1KtA*a^u-9L* zY!g~w*|`MuvKVOwy-7u9Xf!Y?|9e6P7u&CND`B}VA$4yxegPpXu~GkeB`0?{ADi{q z8ELYpe`HFSY_gHhsZFsp8gr6vkI?DWoT%Kv?MmfbH}oZ3*-(Npq`S>>{R;;Qk#E2GA0$A)tnl#_j}UGfBKqb~bQr2}2I^LLh&;7{}~1k*bE lTPkKdEu|u2b(54erY}bg&S%eJb}cliV15~X9>m-X{sFG3cJKfI literal 0 HcmV?d00001 diff --git a/documentation/dev-portal/src/images/profile_picture/nym_dashboard_pp.svg b/documentation/dev-portal/src/images/profile_picture/nym_dashboard_pp.svg new file mode 100644 index 0000000000..e91f3abdb4 --- /dev/null +++ b/documentation/dev-portal/src/images/profile_picture/nym_dashboard_pp.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/documentation/dev-portal/src/quickstart/overview.md b/documentation/dev-portal/src/quickstart/overview.md index a9586172ed..50a6d4187b 100644 --- a/documentation/dev-portal/src/quickstart/overview.md +++ b/documentation/dev-portal/src/quickstart/overview.md @@ -4,8 +4,7 @@ There are multiple options to quickly connect to Nym and see the network in acti Demo application: * a browser-based 'hello world' [chat application](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet! - -Proxy traffic with the Nym Socks5 client: +* a Coconut-scheme based [Credential Library](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials! * set up a plug-and-play connection with the [NymConnect](./nymconnect-gui.md) GUI for proxying Telegram, Electrum, Keybase or Blockstream Green traffic through the mixnet (~2 minutes). * [Download and run](./socks-proxy.md) the Nym Socks5 client via the CLI, for other desktop applications with SOCKS5 connection options (~30 minutes). From d9b4d8fde603a60501729c2688dbd4bdcf0db205 Mon Sep 17 00:00:00 2001 From: Lorexia Date: Wed, 12 Jul 2023 11:05:42 +0200 Subject: [PATCH 08/59] Add preprocessors for build, update NIsNymUp issue, update DarkFi picture --- .../community-applications-and-guides.md | 11 ++++++----- .../src/community-resources/community-guides.md | 0 .../profile_picture/darkfi_over_nym_pp.png | Bin 0 -> 14843 bytes .../profile_picture/darkfi_over_nym_pp.webp | Bin 1736 -> 0 bytes .../src/integrations/mixnet-integration.md | 2 +- .../simple-service-provider/sending-message.md | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 documentation/dev-portal/src/community-resources/community-guides.md create mode 100644 documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.png delete mode 100644 documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.webp diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index ceff0e2291..89248dd8ab 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -57,7 +57,7 @@ We love seeing our developer community create applications using Nym. If you wou -## Nym Dashboard +## Nym Dashboard > Developed by No Trust Verify, this dashboard is a great tool to get information about the mixnet, gateways and mixnodes. * [Deployed Website App](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) @@ -65,9 +65,9 @@ We love seeing our developer community create applications using Nym. If you wou - -## IsNymUp - + +## Is Nym Up + > A tool that helps check the heath of the Nym network as well as some mixnet related statistics. * [Deployed Website App](https://isnymup.com/) @@ -76,7 +76,7 @@ We love seeing our developer community create applications using Nym. If you wou -## DarkFi over Nym +## DarkFi over Nym > In this example, DarkFi used Nym's Mixnet to allow users to anonymously connect to other peers in the Darkfi network. * [Github](https://github.com/darkrenaissance/darkfi) @@ -85,6 +85,7 @@ We love seeing our developer community create applications using Nym. If you wou +

# Community Guides diff --git a/documentation/dev-portal/src/community-resources/community-guides.md b/documentation/dev-portal/src/community-resources/community-guides.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.png b/documentation/dev-portal/src/images/profile_picture/darkfi_over_nym_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae44d85c18872bf9e1789822ec81044e25507f8 GIT binary patch literal 14843 zcmY*=2{@G9`~PE$2q{IxgrbpPdg)u5_^jng2FG~#F!^sxO zSSTvXt3?t$D%7&_Jk*SN;RX0Jbb^7zR&x6BEL(|COQQx`!2=6!MrKXb->2>47QK@% zK4N&KUb3f|WXc|T>ECjxkhN>u$M=W*bn1g9v-|{kV0wYWSv;Pb9U)$PJQ~*96?F-H z+_!l6cY9nWd1pPp;dMUzH0cez!~8{3t6XM-X(_H@KL{Ot9bP;p5{h9rwpsrE>`VLp zWznfzcA@z@Jhnb9IKKNza6-%`3cV1%*a+xN1651qj?2C?VVkv8wL2^l_Uh+4Q`98(TR^(LOFrM_rH zr<&A_JsS{xYbgM+5jE}Y~X$H4tU(3W)gm{=00x7V(k23FsoAA?AdCoud1SSGalWkJG-MdtuC+vcAS|g zemVx)KD?sURs*F0cIy$Zz(n$}>oWGEB30hJ)*C(6#$)Hfqnc`VYYW!=T`Z>gKkw*B zu^h}l%|u$yJ(C}XVaK0Mu>R!DNz!BwlLTZxGm;eE^u}b<&bj3=PV(yVU-zk-mubtr zk`qOTUzsz7Ya*WI9O|pNdL|>>J}X2&% z9pe?j74x3Kx5BSD3y+clTyH!M8q5O=EoSK(i%rus)g7UlNdgSi`7qoHO$v4jM?$MhTl|KTH(3egse7kiR=K8b$vYw3Vsx& zb)IFGU1gW&;KNZ|~Mk3I!4y@k|0E_W9TzVC#u3l5-}3@d^+u zxQOq^`A+e+!ttsJzptKOPcaFdD$9ox-kYAmU#ZIhwmW0GPZEHdwgKC8f@!aklb&YJ z70ReoXQR%C23z*!A|IZzf6LvhzQ}5Y1P@X1eYv(YKJ6R#rq}R@uU9>BKO!R|2mUTi)t7Va{_YjQCIKTbr|_=Z`Rb zceA}Z4r@CLdrvZ9zg7_qMDTKX#x%uhs$QuXQ+7q;wGZ-yN^|xR2g|JLClp5=H)eEb zcK{zxAz+HvkmZ5Ig;{)`>G_Ng)pzDz=0ba`m#eLSrD&0{C}**h;Mho&7T)Zdah(tQ zpUdY9r6pr#4rQPPju7H8s=Up;v#njVM=y+N)msde?Bp$Im#SfrH0EgGUBb&otUO`RBX&=SXWxVq%3Kx^9sKzDqOr8o zZ7;pgKpmpLbMCM=+qorOK@eUVyO57VH}|3=_0tK6r_MoKhx2A8S8^eoCd!tkr2rwyt|mF^JM#M}UMkj@vqf^Z>oD}HO^AxtaNR^Ws^;`xGJ&vTJ)+r` z5lFeb^>#i3iL#7OdPk?8x>KDtfWXlw3pFo{@Ae*84pTn_xMz)xnd%vAmz#xfjoO$tYR}P0x zmYL`w2oWu7s&0Xdw%<;E^cw?OQcYRR+;W&c4rwb@#D|1hd`cs0v5=j=f$>|uulqx1 z@mvxq!8`^G{3PzOvCm8SBoPOJ46+t8*-_^%i5U`el4!zoJpU^nfzgTy2x6$(G@x#( zq?E9rp{q(s#au##zujEPLNWrr9G zFnWApB%(S)Xecss*S-rFDkO##xm3 zhIw&7K(h5<2wQ$D94M46zdkd{E%KNFLn!NnsoqQn28kqs>&vCw-C8G5fURu()BPbG z(GHgTXItds7Q}8agf7u z%YRpHfFK!njwQ5gE6G&uqm5Vw+5ZWJ09elb(;~9h>U`@7#m`MilL4AOuq{5vd^kFF zu=HFC(g6lxu7_}9QPjhEt}VQfuE$G9i;^R)6w<{ui#(`#@Rn0HJ5d5%B;%O`hu%&{ zlI&L#6^MyXDDv}PSfR|{k)#(`R3Qu53k>#sESC3_JQzkfTP>IkLDr9MeyKDScTF9X zIbqKigR#N%X5K(T52og`py!K(gfEntQ zqZ(~qPE{asQw@eDznzDEU=QYnwNm6x3$j4?!Jf#JHwnSf@7Z#*27NN&P%qD5R;(KS zWZiVp3Ix?o*(W)!n#@#OGNL+Jc=HXWGD2gk*Yqe4qdfvEGssiu=Rk$nuS56RHn!wO z_*IA&Nxyi?9!)SoLf-MFY3#%{?mS^5c4+P6Y;3Z?bS3?+EDPj+Pq~`1XY!0J)hR7D zrLpJ*WlMnI|H#bGU5ZTmNQ^b~e8~XOem21gCZ|J`^Ds08Q99Ox2~u0TEZU9MOV4Tg zYGOd;BX0w1?!A?pIt~j&T+CZdUUY`CXVmXoZ1^n?yU&tod8-Ve45xP2=-Dd7gU^o- zKHIjDD1ne|_93+fjc?9-Qk_XWp1_Zh~HIpS`rx z27AiqrA5`>8G+}vf%_;uRgz2TcJ_P|2Ba4K^^t7qL$(a^z2cAJ)ha^}^l27wEYs?& zbf6s}7ASi3Ot<>NUS;EDLk39np30LVuaUxf58J5-& z8y4^*%q-Ay(fGsIIWL4&cvT(*8BrE~=UbzwqX&0hAKY=Ak?$%dY7@+!mAEVeg ztAi^C;Ro~2IL;_wK>4Dg*4Wh#Dw_gOvlcM8poPw;g*!8A72pwLz0z7@!(rmpp|y$~ z4k$ap=i~75-oJrCse?XPV7QJA%9aIu89=q-KslO@9*#s z8{c+&qoUdqfCEA6={|}~-c?=&uIx~6KFZrjW%w_d2jA=CmET5XpsfIXb8Jb#$op>6 z0SVV6s{k!4{9sm{5d>MTlsq`XPBi)oCVnt>7qM`|6M}TJ(PQN9r+-JrQw$IbUmgaj ztT8~Sg5xTiDqsJSN4)owcx1I>&5lCA~igf_e|bDx_3k z?g(HY1yY2AKVrX%<%j;tat%gX2jVJxO*&2eNsvfQtr zazVW}k}Z-NgbV=%H?ZxOs6d($4bP7&95WjDyN=mv&!^s z-A~mwk3gC=U8D4{V%WJ~CIkp-=$jKWyt9D6Z{ZCG0c}mM(A5ZhMPgx4cCw{PLQ@qm z$-o4l++K}hoKa8s7T_#@0BbzizhVN04~~?Xy5mqnFczrSqxef$O}U6?gKWo9@Gc;D?U|XfHW^iM>Xi|9U*>af z1hw_e7Ww81zIJ=c2=Tx9q^PSfs9eRv4%xmHpk^v67i-|gAm|XO3`cB*Ly)7w#)o{} zR$vc`R~Vopcf`iXc}OC9hy$|irGF`R>)Xay;@xRPDhnj*TjgVvK8r_LNkE|{`D&Yo z!8@|qdJaOpGJUf0w$BeYu*j7ZZ$*4KFpK7I{k4l`2o~rE|5CYBrwSh`YW>jCT^JPl zHPu`CzejElC{~3Ge&l0;G)wE@nMX%rFfMv9$abyvII1l{9SX&a!AbdBP7uUp zOuG)BoEdM5atg?;K0Dyfauox>wsp{*@>_LJ}C6npOH4_L~Sz$ zDElQwpj(Lr%GRD-yKBV&<^Sl)p`tpUqNyNULz+&l&WI}@V{tIaV_&e1 zzA3@DGys*hcf@fK9Z_qnP^fO3bIO6pgi96GfNww}e?&UVYudxnWEuqZ|Ehn4xcF*8 zMS&U07We!0|4TKaz=#^r4alwgugC^x91QlhM&eIC--sDu_(q2IG>&aL5Ls(CkPr4k{9K*&Uhem>}zWXlAq1M9Pr^_kpvS! zX-M*cMCkE$*ZkAR#X9FOW}{ZCMrh}E_bCHeUlxuaE9o&pnw@_p4!q$&N%;QYnSOt;aFj@hBz_Lh2w_Z-Kymnyc48|< z$BMQ@r>mRleF|-NQ}oJZlD%!A=e*P8Fzl~U)o0|F+3r$h8u@s{O>u?37w`rp@j_x^ljf9$xI%fh z`Atrr1Bb-q$gQ}vBk{Qe+UKt(P_&^Q98g{ug!%sa^)VHuF9-4GTFqdEgsqUio12@p zL^Uw~^wiW95r{usqexkZXN*io;D)ersj5ey2Vd`yX<}0kNWrtMUroUCo*^NyTeogW zv&oQd~>8Nb(ci%UyJ!EpxS@ix{y4st6E_NP_z$j%+BcQ5Mg zN@aH4ce%&EAFDr!eQIBJ`}$*{foC?RJCpK+1oOhgP?yuZ)nL5Jsz@P~fnN6U-sH{~ z*=l=fd@KeKjIa?6D!(n&heZa>ewp7t)3d7j%P$iUPwTqh5Ex>${fyo()4j8^BcI;Y z2d3ue-*W$QzXCPh8I(VOo^YCTh*rmc+MpP}m}GSzGC2<%&7ASGEH-cOEwxHzU+8E6 zoMnOO$u3oTg#(gZ_bVpU6Znby**pE4$r#!iV$JF0KQ3&*avoeuu8XRZw#q=qMtyu; zvE)}}x&6bm+`8`VT)=x3A@9kxEnC{VSV#5jrAC?l(b?@SQT$wHtV`D~={Men$+eGz zCwTb7q zsob-gF!;@fQ9|t;MP-fO^?h;fO5Kvv(1+POhz2vZCO6v2ZttJI#+&&cnuY!SQ)&Y0xgL8cm5e}CRIs*3hz8i4z3 z`gjI?JKEiP!kF3s>p&}Hy-y=v>jXp*! z{bZ~COW|bgE0c?GV;plo@qSiEaQ0E-7%uL~{s+W6=D+#O$6TvxPa5x(KYYl>Fd*|| zBY7tpj!&YZjpLslWeru~XL|n$_?LB5yT|;5K}<;mxk{AZFuYvu@p3P$sA712vUmNn z!>c?pMN8v*C%vzz?xcO%z2N%$?_6w2RHk@J=SHx2v=B5bL)Fgxn%p|wz2~o zF`QJNrk>F>s1UReu_n@_)4BMnwD6=oMO@8C`ga-e`03Fb18VLvk%x)vyQ<%x4M=vH zW{w)qX{U+c1#%ZN&9_P7f7DlZHg(8EA{kwh<6>QC=QC=N3S`P!zN_5=2{S^( zSZ>aL22W`1oK%U{-zgV9j$1)=2so>KXY_=|GU%nlqk7 z)&Bk6PxmWGYd$j4(t7(DpB?^8?KgdKec#Yfyo<9gxOQT7JMf>)b_coVz`6fj-Tk=# zu)%tWUR7FJdSNU*{`1d)Ar5Wy`V0d90@G0_QsKguzsmYxcxZWKsPqrbn!R48VUbFu zY8@hfyys~wRM@|8G)q0GV0VP!D2lQou_!6jR#;d#(q^0?R4Vy6pzL-6T}Asy9uE&t z(odm(*Zr+1$l%?ruS$xV?Zs`hL%EN~<{XEV8>+(#zxWqRyG07j)z+1}E~MREGRIl1 z9WBvLhP-S`LGOj42o3J*-BQ~P0*JRN=_s5|tzeM)O zT?GpZPM`ZVn?JXCh1|qHy7gnNuc1sOq^c_(@*c{b7xUv*uCm>4o0a~z`UJ|SwCv00 z({)25-VjwAG1g?nY^IG+IDPTv%53IPSdXiQgAGUCO|Bg2)%p2Lr!CAj)F052?#BSg7B6vY>1cY;q zrbCKcvcJ$ims6#ER0g=M0{pzZR;Ly>K06!(VKS-H@%#ArC;x_6@EvS{>OfL+-CO0Z z4+@KlPtS?xm((^i#89v!BSYz3_j|^j>UO-;vxb7X4TxlkrhV_FJp$)FqrC>z9-D@m z(eJ<1(z}Ee3k^ZI7nu0|eRl)tE%?W~v}x{!faAhYVaKOh)t(E*Rw0XxA#*_*K3QO2 zcvoBdr{ei|ud;%`f@so0=1s~|g|C-X-f*aVdNN+OVU|~oynQoM#-_btc|`l1b=^`y zaL?jUKBb%DI^ha7H0LTywH@m;dZx;nKqX~GEpR^Q9)I3?%vbkV$;$*YT#Qo&_n~|N zgLcf8FCXlbB-1=4(-Ri7DMR9Lun>w8*^<6Ed1y%1L+tnX!rYt>|oA79F z>=xHJI=JVR&lR_nTX5NMFiYUT1^cbfBi16O%9<(*+)S0lQ(}L8P0?l}mRc3=1uPLL zKl9YHZ)W6tTN)fxbNv2c^NLW#S;L?+^Omwfi!-+cD=fl+`#)LCOybOMr~i?x!~aM* zDwhOXvntXb-dQ1ZQ|M}Mo6;M)x%DHkCUKnkI8?mS2~-^C9w1UgwNx6o7$ecWQ!HS- zr+&Fs05$W%wsKgl_?STYc=RK;WCsJ+ceVVe&XV^5()h&*)*c*b?g*)L;CD)>WxH;^ zc$@P8>-l-tsc$9H#WEK!Q_<^u1%}aSy^`993 zS+kY0^fw&_H*Rs}*GZ@*ZrAmUbsB<{0&2zwo?^b;eCJ#?&FVfI@zW1op?39~+vh4& z?wuxPvleF4mA#@QYV| zV3EaUZQ^0hw+2&$>rPhAvz}^dkCx_&SoTT)QRCm$`o72gDp4OrOG-+n$V4Mn7_DJv zsX+Kxqsoz;l%a+l8dsHYcpOYa_rr$fruJgtSXI;e_uIcTx5V8P)3??rXadvsO`Dm4 zfdQF_r6rAo*Tp-&`_!ezjjk?3a6Y*O%X?ec=HKw}XI0{!PoZk|G$FvX!5S7Mq#i`$ zEga}jl5Ze-xnS?FHe-&38wCGwRcO0VsMxTgXm4_Vo$-i&(P42r>E!FIWY}t;J&-B>YYm&s1SSh@FP zf5FEgtV`$0pb`i6!eHpZQ?lCj9h zh$@_6YR^pA^@#d_&BfUe`+fiJ`xW5mT;dsXzhXE(L_O8uo?^O19p~;bRLFTI+yj3R zI$ie#y8Lj#zBddbY%{bSD7?C@Djt8M$h=TjX(AeA57!!0GEmbS8`Y1BiDXJ!c(vqa z*g2-&1`K=E!KwVNv}>07l0ehH;hv@Hj+;65e8xapQpx%--B{UFgWyyKzr`jCsgno% zcfj}yrMWTgIRQn=1allnCy82-T@+l!pn-M&lG0LGYrphug|hp8Qe2!db(B4Ob^c^W zKQ8PmPLqC^PWX3=%EJW#EtQLyT8{jsiKcx=!&SO?L+y|`_rUbn7H)qtuGB&>g!RGq zxQc{6OQC$SaUC%>cCJLuZl%}t-LTsf_(@(I36{X^%OB1(_b%8=8QZB-Xj6Z1WuJoY zixlxT+LNO$1{sUv)vHd;5t_X~5I>6Ae6k>&Ut(VPuBj>R<2}2%{g-lfo=qh;iJP0H z1FkURA|ckvgqNo*H~U8_T^>Gsh&*8cWBoD&EDDSWnT=iKiU_HX3h_~N5sLdDG_qbQ zH)@RY-|tnJ%v;SN3lHMyW*l>h38-8{;{ognzE|6(XYo8~uY00|Tz%(O1I#SBlW-2! z(_h!o^VmLb)28lZ$qDRu+qAyW2P3gb2R5`*-hMDAr_~PT5e|3L6_J4=HevOBGF1d| z;Lt!c$`WoZ;0g$0sG3`&>%+u@dY>*{E;h=gsW+6m(h9Y?krN^Qx036tzt}3KtBsba z{M3G7OWS1~P$X_e`WH~YVuG_gL@Zl!$uc-0kmq2kMrD%+8t zxjxPz{`)ImO@RhN=36P;gzOtZ^O-cqjY91~@9I+qJ~@AkdkiT{iW*&;9!(>HbwXJxN=a5Ytqbi%YL|oR)%`EdFuF5-&YeyVTi$gLqkvV zjyKxXD&$2hrOAe=UuF|p?yvXhSnow~7#`L7|lbd3|#>Dv@|5eqHbzI`M z5^%_tB_Cu)l7F#G!;<9Ym9dFyj{99DL2*fbdxZl9RYQq0ek6aIg%j583tDf~c`xDB z7_IU(^_u=L^ZFyFNAK^dtDbPK7*T~3wrASu)O2>SPmc>txi` z=^^_Adoon3bX~V}DxVMX4GGzI*{uB1WRb^l+h=C2_u;y}&>C|5)^Ny9FSYksHw7M? zm#~0O$|#eK4sUnVqaCOXoOJ9b1CXR9vUYUZRRvV5Y25gx>Y!! zHI(bZHXh=!GgKb4G?Uy)frn8p!L~N3>s!ID7v=?ZFLlEr$b{GYR++&drUnS+j#S^4 z%B=SQDG!44xIOYo4^F%={QV50i;(_#Amfm_@CZ~4OwgE{6LE8VW^XSj4ft+DjkdPu z@d`Ggr7(8htsf};kJ@3PZu+!H{33WMZRK~5Qyi3@ORKKY-{GY`jk5^2eQkN1rD?zg zhm8!7%tndFk0iGwa2nsti|Q;Ai4`#V15yxG)52OtmjQ13_TWUYMvN!FpiW>7HI#Pkho48JnSnimg%WhP>8FXE&nj?kmqDJ6?&qwMJ z6RA3K^FatoxsHGpG&4dS??K7X^)>Pai!7Lmf?99c9!#X z$XUcXrMgGFY24M}U%zdwm?APH|GD&Ykrdm~+4N!In?iW44&lPgoIv;rpaCcR`@&d& zhv#qIjvY}3UOiI`#H;A(oxkM3!R*buxSxK)Fpc2o$Ve*Hl_h5rIKodq>(M43Pfs4| zx}{x?GANEyw1tCsQ4_i!_R(S}cVxz=dmxWI@ul3r&hBXowqp3h{fg%xn+U=wcZec5 z!pNn5Xpe*0gUs8h2Q26ZA8~rl^yQF+8j}p13)Z>+{YJm#r8fSd5z3grs@%lR&b8;m z2nYV+*iNS*JQCFr8Cxt^D3(3K?8rZT$I1T-Yu{&wdrWvc{476drj=s)GP)!hsd#Pp zUt9iZWp=}MvMenqy5DOOTVnjlxE54v!Y`Fj0$ciJ{go8sDrSd|N0}Dy=3NHqMyce^ zj*yAPK>qfg=OC5&ac6VM-8xJ-m_vj9#KxO?O~=8)TbO76R`KjB$!q#uGhWxk7&L44 zYS9`~o88U;Jd`o}J>!m?!$UP|8>* zBhWJ$AVD9A8*VZNWeUn>oh1{r{G!jWtD?H`C36f^c$`KNDo^V_n3HLhBu5 z^XuQ3TC1u|anN&rgVK-vm^VnAf~pmq5cf}k7`|jc2nv-jdw9>Bi+ELlp0@$4Ocj4J z$pzGrGM7M!4h;lLV}jn!Ifq1--n&Kws}e~1AJ&ChZ6 z!y*)_4k{3>&Q>zaP^k5eMZ4G{l^s051ljhxIGYb1Lm4hGfdUZ_Dz5Pi1o;z_;Cr=g zls+5-#7`JWOQ?E=M(+TIs^;$^ig%uYY6!6jsEK?!`z6ZKWrd0Ew+@rx_l62GKV#3K&U&y5;B2e?0T{q-tM%A*o0buw@ z+tBOnZz;M;I%GYdstu{jC^nc?vBm;JhKO85ftmzS~nG+P)MyLdr&yH$cnnJR z)PS$2=c7@@%0a#+gFs}Jldmrb=6H7_E%V<8082BevEl&BTEOehg1hqbucIc{irQGx z>zqK%?d#_fXPpQj-CAHLobP8{5NcH4$-G72OP085SAnl9-Of5XNsiRWtyy(ODF5S5 zLSJ5?%wiEM3%)J_f?Pbwzib7*KIwLTx(IkS9QOfbg!MQ7pf`^}03=o?Y!Gl96?J9& z9Uw2ceTv71wtS_>->kpqsvQU$PMM}O5&U5O`B}crlaMBS0QET9o-L!J6zBYB@MBAeaS+!oo@fT*lYR>kgEH5yX^=Swl-c}t zf0g3>n+Gef$+ zmvWfNEzihPt-A}t2dJ5VBW}*q*?H>+TSR~$j}OmE_Z~ZR9#ez>tB!$QEqxWdE8vBx_uwtxR5n zKgk#j@qJ>kaR4NOF+ohr{{s>=wp8%k{otH3&I*OwssFS^zQDNn!yx`hEu)#GBf*yY zlQC)F9?f-`yshFSR+~?jZQzF1$bm;%ux5W}=tb{G+aW`oM6DBL!@~M&Uyn6sN(j*sM4hnPLn_-{c1@J`Wzp%wKc#wtd#LxlwO=c#Qop_Cm#ksLJT+|u31*7VCUp$ zJ7JaG71hbxc?b?=tFkU|5M!Q^Yk11I1m8fRZNtz_F#EC7z1&d3+6~zgsC2IU^vHj2 zGD5x|4fUK!fS4e|Isjt<#OQJ~;E^Q9Msz>a@2Im|4185=qD{)xQBgj z&K(^Mg8NhlkfZp0W(O()+VWe*@SrJ0JkgT`&Zw?}(B#3+=qp3FBWE$?| z<<38mx4{h29Wfc(t)ruR6KsD{QG zOO&albAmaap;5xdAs@V7*Z|fi_IM3;IxB;-WUP}KViu(7aRm$zcZ#Tj6y0tJL<6{^Jk;D1;G(kHo-Pq8(NN7>kMOsva62}du?sU}3T1d?mVnXY zW||v~ysi5otAL?d^V>@eOx`+c5yE9o?z93+vuxmTg9xJ;tQ6k}Dj1?ID2htE2OdM6 zGS}>~uj5(=vgs95QdEzLaNgs&0WTJtQmrP7LcOe6%w*56%0kmuYfRWf7b{kr-(XSK z9(d&TSAh{)!dH>^kVN|?hVps2YAZ9UF~ck)RsR}l2K#d(^Sq;wBt*O)1aF1&e5|}7 z+^x;>Lmt5TVVPSx0MRZyanxc%S(JY39Q5G%s{Zz~Zg|smc+m4mjTc5`Q12URf~j;$ zxzS7l(c?(FAww@7G!!J2B!&U-lHaT8Jm|r{?rw3V}t2oCU8?qwSfEXig{= zlVO^6fvFXaV>To2LS~KvSx-_2XU+tWclR#_{|hyX&<~Th60*JYw$tycbTvgsas!E7 z4%Yopk6=0U6m5B!WFtDIA;|z7SoEHy>Q5GMjWZu0iS-)*a9?z4DWT8FFwPSonLmt7bdV48;YPA;=%wl zTeS3_)D%G?yEdUOE}>6eRQd%h7{Ydf_hZqNN9;%Yu@>pjM>6FEs_(KjRVEYXQwD9}Rlh7teW(2cmPbZ~R*NPeC6 zu0}-0UZ^p9E1Zo4#jH3;JVhThWkB-i&A7 zv793KRm3x%i2hCt^9c;i*kw~KScZeRtZ$sbPST75RwP%QVVcAH6z!|{2DC@jPS~3~ z&bvZMUe=K~3R-BctI1rMOLT!0wm`4W4&lG1qy8H@25rCL*#as{T8L-5R|>k&%{hS7 z(A&?4pQ0bY^M98uyrGi>z*|?Dl~HYFCLoWvdOhQVcSndoElKvi($zCo7eKR8Z(?>W z2g!T84G|c(U}CI~-UJ;&$=Y*gtI_o2oOE{WH6xzuO$TjFy*1hXr$!$ZRFQf;244Y2 zpRkiWrYEXMFf(REF))og**)3##vR%OGP@4CAS=p94Y8E1TGBJU59{BRy;OW^ewq2Wy zg^Q9AwE!UBAX{s449uOzRtSXCUC`VSe6-<0Sbmp2;1MhOcJb3$QT2i^KLX<-4SC0U zBfqh|1~=B=l_+5r^PH*>5iI&?Z`DC#pzP1yT8-xr#ZATM2iejjR-Cw;HlAy7YwNP8x0~hq&eDc%F8$BnpH*BRxi6~?{GPcheXw6_w U5YAQwFXqsVt0amFLAw_r}@5+T!CK!Ldi zP>lr)5C&&5)WhIIg%Pl=dB5fIf}_9tA4}1#ruQeAppEj0N~yWKwdroI`BNj0Qjf6Bc%Y?S+-Xn9K3opL)#?w zHMnAHtL_pp`AA~VsT9+!fq_CqV%mZtm>0$U*)V53;Vqa-svWEw%u~ZlTQq#q$r|e@ z*qFPkgk?-*siHcVg=WOpU0a$fosyd+s+3? zSj3Ii&$#-fch$6e=w+WP!R)YE3X!G$7Jnz_kVW?Ww4OTs5lr;GC*QnLs4*k);u zev1G2z~k>9yg!VvOgOS3GS!35?e~Y@Mx92Et3x&#(kwb*O@MZ5ix39KVUTm?6=(3)-diBQa znp=7!FQ)UFk(z+Vr##eXzE$ebTxFo9!p%coPfsh@*CI~|TJ9FKmm6jT_6@lSYZoIg z?MAp&Ap3Yd>?|wk2RZUR64m-{r1W;HY4QvOPZqe}LpMe%`f)rR!}Mk-c0V_e&SR2P z!}vaaY`Ui<>EdF&L2s2qvU+miMfOn>n})XMQv;dC+}eV_at_{fywJvWTXvYOzU(-H zdQ0pm*VYU>WZl@anMOCLsQk!kDAa4h1@y|W=EG6rvPOIzGjyjF&h?1w=z$aua_Fpy zpOcI#MggI8I!=$LaL$TejPm!hycR;=Uo+{-+wtIArfjuiZrk)U=8Rs!IB5f6x>Tj2 zTs9$)(yp<|P_Afn;Hh?T`R=n@!{ieCwuxqsJtA-7m*>=^bxO*Iw`Cen$H#lVIf8ak zs};uFHeWJ5->TC-#>7@M;c|2YW4@M>QEu6rnF4#)prr%r+fGdhw)hx}NEdd>ybxMz zG~!#l^!g@IFF`LlxQo)N*hrYu#bUXoG86l6)%)ZYCCW6smqTE*=elgz`y7W)b6b5Z z>*F*>ohRO*?e_q~?&v+on;SFH9xmMqKOS~9qTJUsOKGn#oqE=aI!;1KtA*a^u-9L* zY!g~w*|`MuvKVOwy-7u9Xf!Y?|9e6P7u&CND`B}VA$4yxegPpXu~GkeB`0?{ADi{q z8ELYpe`HFSY_gHhsZFsp8gr6vkI?DWoT%Kv?MmfbH}oZ3*-(Npq`S>>{R;;Qk#E2GA0$A)tnl#_j}UGfBKqb~bQr2}2I^LLh&;7{}~1k*bE lTPkKdEu|u2b(54erY}bg&S%eJb}cliV15~X9>m-X{sFG3cJKfI diff --git a/documentation/dev-portal/src/integrations/mixnet-integration.md b/documentation/dev-portal/src/integrations/mixnet-integration.md index 43fea3e7e9..e4a328bf24 100644 --- a/documentation/dev-portal/src/integrations/mixnet-integration.md +++ b/documentation/dev-portal/src/integrations/mixnet-integration.md @@ -36,7 +36,7 @@ In order to ensure uptime and reliability, it is recommended that you run some p * If you're running a purely P2P application, then just integrating clients and having some method of sharing addresses should be enough to route your traffic through the mixnet. * If you're wanting to place the mixnet between your users' application instances and a server-based backend, you can use the [network requester](https://nymtech.net/docs/nodes/network-requester-setup.html) service provider binary to proxy these requests to your application backend, with the mixnet 'between' the user and your service, in order to prevent metadata leakage being broadcast to the internet. -* If you're wanting to route RPC requests through the mixnet to a blockchain, you will need to look into setting up some sort of service that does the transaction broadcasting for you. You can find examples of such projects on the [community applications](../community-resources/community-applications.md) page. +* If you're wanting to route RPC requests through the mixnet to a blockchain, you will need to look into setting up some sort of service that does the transaction broadcasting for you. You can find examples of such projects on the [community applications](../community-resources/community-applications-and-guides.md) page. ## Example application traffic flow ### Initialization diff --git a/documentation/dev-portal/src/tutorials/simple-service-provider/sending-message.md b/documentation/dev-portal/src/tutorials/simple-service-provider/sending-message.md index a1a5f67ae9..d0083f0a01 100644 --- a/documentation/dev-portal/src/tutorials/simple-service-provider/sending-message.md +++ b/documentation/dev-portal/src/tutorials/simple-service-provider/sending-message.md @@ -12,7 +12,7 @@ Simply fill in the fields in your browser and click `Send`. In your browser you -This small project can be used as a template to start conceptualizing and developing more complex PEApps. Stay tuned for more soon, and if you're searching for inspiration check out the [community apps](../../community-resources/community-applications.md) list! +This small project can be used as a template to start conceptualizing and developing more complex PEApps. Stay tuned for more soon, and if you're searching for inspiration check out the [community apps](../../community-resources/community-applications-and-guides.md) list! From 825f25800a17e101ef73f37c21c45cf2ac8ebcb5 Mon Sep 17 00:00:00 2001 From: Lorexia Date: Wed, 12 Jul 2023 14:44:51 +0200 Subject: [PATCH 09/59] Add Nymster email info, update Nostr-Nym link, update deployed apps text --- .../community-applications-and-guides.md | 26 ++++++++++++------ .../profile_picture/nymstr_email_pp.png | Bin 0 -> 8577 bytes 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 documentation/dev-portal/src/images/profile_picture/nymstr_email_pp.png diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index 89248dd8ab..3c817f6541 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -9,7 +9,7 @@ We love seeing our developer community create applications using Nym. If you wou >A [pastebin](https://pastebin.com) inspired project, offer a solution for sharing text with Nym products to offer full anonymity, even on metadata level. * [Github](https://github.com/notrustverify/pastenym) -* [Deployed Website App](https://pastenym.ch) +* [Deployed App](https://pastenym.ch) @@ -17,10 +17,11 @@ We love seeing our developer community create applications using Nym. If you wou ## Nostr-Nym -> [Nostr-nym](https://github.com/notrustverify/nostr-nym) offer a solution to use [Nostr](https://nostr.how/) protocol by giving the possibility to run a relay on mixnet. By using a nostr client compatible with the mixnet, users can protect their privacy to be able to use Nostr has the want, without being observed. +> [Nostr-nym](https://github.com/notrustverify/nostr-nym) offer a solution to use [Nostr](https://nostr.how/en/what-is-nostr) protocol by giving the possibility to run a relay on mixnet. By using a nostr client compatible with the mixnet, users can protect their privacy to be able to use Nostr has the want, without being observed. * [Github](https://github.com/notrustverify/nostr-nym) -* Deployed Website App coming soon +* [Deployed App](https://nostrnym.pnproxy.org/) +* [Documentation](https://blog.notrustverify.ch/nostr-relay-on-nym) @@ -60,30 +61,39 @@ We love seeing our developer community create applications using Nym. If you wou ## Nym Dashboard > Developed by No Trust Verify, this dashboard is a great tool to get information about the mixnet, gateways and mixnodes. -* [Deployed Website App](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) +* [Deployed App](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) + ## Is Nym Up -> A tool that helps check the heath of the Nym network as well as some mixnet related statistics. -* [Deployed Website App](https://isnymup.com/) +> Explore whether we're up through IsNymUp, a tool that helps check the heath of the Nym network as well as some mixnet related statistics! +* [Deployed App](https://isnymup.com/) - ## DarkFi over Nym -> In this example, DarkFi used Nym's Mixnet to allow users to anonymously connect to other peers in the Darkfi network. +> DarkFi leverages Nym's mixnet as a pluggable transport for IRCD, their p2p IRC variant. Users can anonymously connect to peers over the network, ensuring secure and private communication within the DarkFi ecosystem. * [Github](https://github.com/darkrenaissance/darkfi) * [Documentation](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html) + + +## Nymstr email + +> Experience secure and private email communication with ease using Nymstr email, which enables seamless transmission of emails over a SOCKS5 proxy and our NYM mixnet! +* [Github](https://github.com/dial0ut/nymstr-email) + + +

diff --git a/documentation/dev-portal/src/images/profile_picture/nymstr_email_pp.png b/documentation/dev-portal/src/images/profile_picture/nymstr_email_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..404b9e25299e21018b47fb76642fadd8177e36af GIT binary patch literal 8577 zcmYj1c{~&T`|nvfb1af;sVS19M24YNLyeZHUX>-WcA+w*=u@8^D=_wnqC(;+)qX*Fp8fb4<&1Q!6r zsG^UgI2?I}Yz%a2+FU?Vs{*mE@e-537*5Ouq!<1@Lg3xk$_ zEIirHO~zZIB(Y*f$Tuhri_5WEm0_!7eDOAHuT|PwuG1%T%O`>{Ll^M%|M6c&NUpid z8JoTDa$i8KdYFTnru+bS25cnGW2{RapdW2cywiBAp?&Xdne3NhaE`pfC_FD}@BZX$|F;_{vZ zGp!TLAKCip^|p@$ZCV5*iEpT&RM*yG$Iu2=gPCu?eM!!D&K1Uj#)b4q1WBSsHF)wA zvuX70{j7?|#22G)g%}Lk#r|j9>KK+YJ;Y|Ubbd5!fShk!gH-efOj;Ud&IyY41zmS>S6Qn-tz)BTi~1uiO(ltwekEfO zR&WThm%KEZ=zQC*!u*@^Uila_J2%tAZs7j4e0m2*+MxncPu@qqp+!cA9K2r z-)wO}6V%1BX~5#cq59{~x;`6<2G>YP;#7{jM2|5%Bv@|d+0~6&?H?LXo3@umY!u{G zWil)ki@vvr(Ku^c{PuD$8SPmSi_F)uk1v9kdolpIyc@HEQYJM;8aY%RYMx@qZ~$+3lIk zhEbOXp`V7Pg(D&Nss3ho-gCRlLVf+Rz5Y=j>OvKEO5(z?pR`dS8y@tTI}|xhYxcUf zju0~&A+Ppm@&&?`KJ&t>Zk7sEMwQTPgWs4XPU5@A?nK%!PbmhSq%(f#Y{vzxTF1j? zjc{z77)c^fobNAZF?Bk2rn2plUzRdSLbhQb#dEYj4&ObMXBS_vX3gwgAuT#=I1 zkOl7er3;+4OBFkm{x=b{ioaREO01quNMs}TNJv7dH;#i#65JH=%WcoO_;s4chVy)4 z&^4-*v6Acp#W1|%C9H!kQAIii{qVBTWF_MftxBw{I*~D(_V(s&JkO{nj~SQmKrc7L ztR}q}zf4|hY6}8OpNo-RY`sHPhJe=m%f#+a30V;NjeCcqmiLC7d}Py@A*M~g9V0lk zX&s-dbRuHVJ3^Uc zH?xO!D_Y2W19&g5YJ?AZKKFD@IC;XEwgKhfEWy4Rgeqytz0Ec@rV7-;QrYHWUYY^L zUVgp;-j)epQs}C>r@Z6O+gf-t*Yj{!y7l?%^AR11{jRNpd==?($SY7Jz_TkBbk7S{ z81GvKOAL&u0cv5spFteyM@n*5iBD=FGuF+5emk?)$H!L?t~U+?WXm{62vJAfqqcoj zGp5!kQ^rssS`#4Q>lO_8R^*E_ke}svjg?rQ+@Sj<_GoJ%v+4BbU8=Hl3+rm1G84`Y zC4y_hN23Wt%t-DXxx8(A@=&IKdNq+hIMb9(_k$Pcy@;qGT`cO;lGz^r||uaGyp=w*>UDE|yKh-Y!HEH-q8on!S$t zM3u50HFK3cxz6jL3t_RoxNnB7)F0J>j(4*Fe>#*NY3G--A@8 zNN&pOJ3>nhvo&>^Me-&;iu-Kc5(2l6Yn&9T)7H3x5fpBmP$qp|M{f-m78|8|_g|?_ zowh`Sez)B;n)lWi^hW~Ujj*Vka}Vhisf&pU9b~cdlL|d@4@&?}@E{Rs>2oZoqi-_; zuNm;S0(Ff7B~i3|iGBZ$OS<=DVs$E`5=8;u#vKR)yrY{0#f1OA2fW)v&+a!nyiF4TKOlu8puvb7 zNk;^15vP;`i&N(|Acx|o@0 z0p`L7K2EvB5K+!Q`TIfLp{I#B5;m-h1*dpt23YEGS3?J0y~r2pW0pyqf!9=&y>6>) zG#huc%Ta42*H#Rio4t6%UZ$Rnb|~q$;~yX#SCs+r&~(Y*U}t=K7NhyQuxzkq}pEKVdGI6`Sa9#w}kH-T!Bi_o0`K^CDND`8|*lpACW6?P4^yyp<=7|QTdeTEUA~m zk06{6J&dd?ywL2}@#JoXH#$%ZSUN_ZT9i!d@e^o3=;5x5tL#ffxcVY+@lD2nq~qzc zy5*C^pdi@p(H=3GY_BY@YvCy(f#sjP~O#bLvTWk zV;1_;@7eO~lwS07!n5TsT^s4`>vOkL%Igp4J4kjQ0yax|bw@VCam@)QutwL3J@Mg^?AB0=#H9vJ44(Eh2oq zK45F=ZaZ)|{5^m(!EMW; zfI7s{h;m}GF*Wq38pt!>CeK;ik#9T+==jQ~FK=mx6kK>(12r?qU> zkuo$rEongrfHZq_Qp*PJ0;SV&Qou_^cUwfP{|uaVUlitu0r79Oamh-%T6nDk4uGzG z-%=#I>Fngl3i=5+Kb#-NS|# zIBuyCBnHxSZElZEDzB%?X^DevP9JVJZfWDSas$x7sT?D3V7N_icHSaM1r$F2`PTP~ zJ+p*aWe4a9O5KKyF|0ldkhj;S_1#SqA8cq40PD8hB_&957F~#?6o5~DI+l*27Th!h z_#y-2aNbAm(nJ&h+kTYAxN+9{3VemDK^`I++nPtppk2=_LIU?`$~gM*zILb@65#iV z2Qr^?+o~X`XmP7v@=H}t)){$Va*Exgx>?ZDg8;JX0X^hG(Xbpa3Aol{9?qi>Vbb0! z#)1xZ=YVBkJdtqAj&QaXL60jKu>2B7H0%xSRRb!QX7{zfL!WCBnuzF(UK^>qnv1p& z_!b+19T~d|wT0KZKI=%DILj+a+~AR~z3b3TAk+rVtTy)URxh!eq7# zRJg7Z{h!!#@|>F1-pP7EH(H2dheEHk1wk&nB0~ zQ=j??+K%r7^!g{xK_a@FF;Ac{`8$#E zp&9`e4@{gK?THEr}E14|X?eCs_MJx_Xc`kO{KDg_$C8##%CBHd9g|+3Sow4oX?-G3=N>Ag zqJUm?g%mv2^17f|f zWey1ht%m}?4;Q#LvjM1`n?5TrG^VDL5a7pDeexCo0BTYkd4tAJKeLt|g-C$$#)}1M z!ipsuO;(99^i@Z$d|5gaQYC`tn2ZJZAnPu74^dLwLtRf2!7k+DsCq+D0BCS~TEAas z&z?sE{K_v@Nplc$F5ngdocn2Bacnnfz3(LSg8zdb?@R@Eo7RINukzE|NfKa3IeW62 ztd?Sq0A~M5QxACd4`y741Fz2v0fNKTu{_cBjka=_*o(GnSW!C$=zA8A*?(THUFp1Q zOg%Cx1$Ja6yC38sfFuq8dua|Wx8%1NsKE}f4bB<6D+U&V@JFqK9trE<)%7D!R}gRufUPfH8IrKO zU}QCBMr{?cd!f6vS} zLf^FQ)Cc&JIi>@hsyKC+aTB47E-)Bm0G@Jpdn_7OEMp%D;8gM10cwtK6bVBh5PB){ zaY&G7ty^#yC9*(vh|=&H9H3_xd62Dq#za5Qp?AwdmH-s?Y{rai=cWWMj=eu7KD_SY zQvdxuAa}d<2^AATKn?(>8Y~2Nkh!fWR7AA=p;gyF8na0-ZuOu` z=+LNmhz|phr6LaK6D$oI!cIAe;*jo*0BV~cD~JZTa0n6*p)0^35z+hauxRy0i1q)5 z|0VkG@c&yZ!cM{oEPl%-+=?M5LH^&#|C9S)!nHAc?hfd(AX1YY$U{L2qLohWJcBi& z1(whW9nw&s4kw<0tY{?NPIn80ovProh70teRu75hw-x%8^3z0+-UPkl-u#a_dr0uk z2^Dm=l!aPs8xtAmmjU!GKAJ=evJ@>@iR2Zek&~doSUm=Qv#TJvoH%~jFf@DH_kTPO zVQw%K&~L^?B$$ygv+8*yKfFXdFf#;0Zvmy=7)>Ma#w6dF(o8&>BN>F)UB+1WQ8RThTInbMP zP+FgvVYY*=6g2qWnqFT!^+jWiqiev98X7YomF@9wv0}!sWTAuVBP(8sibU5iUpo>D zCHsjAIirsN;-O4tKn1)13C#ELR$Bw@|AuIHENcw@6fb=w{iuj*Snwo? zf%91dIyjsG&!rf?-D?!ww)(28tk*(=i^hwXXC|RW#8{uh0Q~Cu_-O(wuy(%&z_)&P zO<7!f9|C+E+gBvodYUwTd!*9z69ADkmdE4{Qia0-G0<_?M`Vzac%rq`d=F2whkYpz zV)7h#CqqZ&0UL`e>n{Fn$ln_si`#ZqAJh#Bo~+@7LX=(v@S3~(&h8(l4Yfo7H6F8sU#efzy zi&-dyH^$pyKuNICAnY1+9iPxpc19W`bx_E+O}WBr1=7GNGkRACJV(CKfjidssD@V? zp&gH(0A2*Sch>Q8oCl2Y<37M^RrP>%U>tGq)1(^?c&#y%3u$=eMXFeKjDv7qAaTu( zEXp*y`Qy2d=a4{_WAQD3|C>+{$RkBRX@kFA+~aza5FoI+rN}sit^W8g1aJ?$1vx)N zgO0rCzLVmzoZE>ogUZTPO$2A(cyeF`7C$a;?tu;G-E@LcTx8NZB%%`|VoC0;@^3;@ z3zXpb`HR630z5yL?NbJYZ%#^;QW|532MS=lIa9BsNNp=af^A{u-wyFG^~Fy{R)fMK zVuCcTlnU@R3E4$@hJu{5pfOJbknXX$q?g!uviM~ZKWYxIMyD<$50_(Hi!Y~ zU>3Z3eDV5Z4R@>qNK(d$zb8Aqf!F?wssl0n9O=FpXnlnQ%cRP8?9fy2ke!E-*D5v@ zoE>Q8il#{XkK*^a&L^WIKP`)aCw7p6rhC|;6bP2=-4&2oXev0Z?+1&1_bxk%=%TdP zSSt=+XENMP4<1ER&4s=st<|98>faF5r1oVk$bk+O*%)F}=1hE~JmBSPmIY>>!U%Gd z%CPWFf1$(Xqu%8|;)(X3t+z!q!hNRZ_odHkfEZKy1w+xE53`6XRCnZktn?r> zJQ4;1m76C*kxAUG>E5|#SHbMD?X+Xod^i=ez7Mq(bUgiZ)f7dYSwL+a6Vkw`cM+3z zOi9j*N~T>yLF5LI9hUWM(r)Zj!}=vlXq5%fk=Cy=^LpS^y{z^0B3a|fsC5FFw=tYg&US2JlmdKdvgHJZ=qBe9!dSQoEIqSoS*sF{w z_zf3^htw-aG%^*0HqS2+>k#;d`aR^}GdAytlSpRNpuExiQrv{OdcTskGJfD9SK}#1#T) zhCxW+0CBD5Vq)G?jM ziq>)u4It=+`*>GyK!L)QgEy@^@Rd;r0r>rUP!jjQL421Kt^vL_T99;vN#fuRe1a4L zeAgzyKZEg=NZ_m^2*(QH8}=C!P}mSiI7nczM?Y3_u6DPuDv^0{h0IS=hB4?7IpF-l z`og*J@Ey{z6V>DmsQ1aM!0M`lx-8YWomnM%uFKJ({+po~k{s%Y&`%3dR~MyB`B^* z3(is3KVUt&Q;hKyoL+3dCwdUFA)Gf-1K;XGv~TY8Id)sekKbn`Q}>jZP<<||d^x(*1Ta`F3HhpFr*U z3jPom=ZoMC{G)w-OJ(VOF}h>l<~JK1N|Gn4g_fA*-0NUy_3nFVhHIkP`NfsYIP4!_ z`on`wH3#WA-xQj>chG$n9H_EuP0HCx-4jZJKQDMq1fGcT5SV8 zWZau#&Ds}l$8{0#mSY~ZahUN1ZuB0$Z9`W6!KTI}{>u-$hdP5dOXHh+?6Mfu*NuFz z-t&L_wVu?gk2lu*f(j9KdvQ}{n)sXlw7cV)y}GbJ@L|eMH#KQed>z~#R*cqyKYn$K zOU0nup`qnW#0w|#aT;bVil&FBIg8JCTw!S1BJ;v`V_>+2zfMALU(p$wAeNTyh?H;| zunQx!)J(1;y(kaCN~!Asd++E~L64Q1AGp{zFIqf4ktAL>6!q%SYDG#7T&h0PBu#%F z9=(d2GAI_LjJk+j3nXS7?EQUJ6sX@+X}(k7*U5A_(u?QFAY};rXw^q^Q=X5I*FNau zh%BVj3%gAoYOu?+Pa-FD3Rusf)Y=O6@tnN|&@WE^_;07jwe>Au9pV&-51L2}`sE|0 z?{GB2WcFQR=cm^(V_VmO_C5^=ysKo!KmcWGw^49v>-1exgtCfGbFm~YTeilHa4Vi) zS|@4!6*IzptjA618HG~hJ3m#I&2!EuvEcsYzg2;nv}O9P`LyLli6)XapSP{%IIkt8Uqa-vf%^@=)nuqS9XeaL55;u!JC4o}*A z=#YKKCP7~EOI&jInjF@X9UGu!S)84)1$fGM`q0^-zEg-V)h&ByK2XaYDRmyZ<7vw2 z{%cLkyFe!^od0Vqw3?IP%+DC?HRK~Kdgb$;tSZ&9ZQcx!WQBB z2;Z4JOW!frFguyba(d26W#dGv0&Ey^gX!$( zr&>Yi@buH9i%|^|3d2>m;iY%qs=*LT!|o^}47;p9{P=0gK`BYxR_(9auzjl-!FFpQ zMv$Ss7?uj5kiZ_TDU+H9=^<4q-P)2y&}P|5HKRJ$v9g>q{sQHzjKfLc z2sy>Nxtj$5LPzvp0Fzs(b}Zr9mj)UdYq)aZNi_#7+deqf2W*HP{JSLkrbo;csBK-- z?FzY?PBtQ%#BUmXI3N-lNlmO74Zrn@DQzXEa5nL~eEaK5Y^0pxIh}bwPGDanC8bh* z6O?4D){ndG-tETcYQi5_CRWC7f?fJF&2y<55jux29~LBUA0g+&3?#S8!Fzj2JOf(M zX^#NCTdMZJ@^Dt|W1?Nd&K1`WjM?K*eAwStJ3sjnzHwVDYY%VyxUZ^tn5u~SX+D(h zI}D8`!2LROR^T}M-hCzDZV;|_eylMycM3k*$B8RY@&3cuSG#kX-fw=F`<;{At>52y z%HxwJR~AmCBIZmM;nbOn=#WfV&B Date: Wed, 12 Jul 2023 18:37:06 +0200 Subject: [PATCH 10/59] Add Minibolt to community projects list --- .../community-applications-and-guides.md | 10 ++++++++++ .../src/images/profile_picture/minibolt_pp.png | Bin 0 -> 13877 bytes documentation/dev-portal/theme/css/general.css | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 documentation/dev-portal/src/images/profile_picture/minibolt_pp.png diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index 3c817f6541..78e0916d4f 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -94,6 +94,16 @@ We love seeing our developer community create applications using Nym. If you wou + + +## Minibolt + +> Anonymize your p2p inventory messages and mempool for your Bitcoin & Lightning full nodes on consumer PCs! +* [Github](https://github.com/minibolt-guide/minibolt) +* [Documentation](https://v2.minibolt.info/bonus-guides/system/nym-mixnet#proxying-bitcoin-core) + + +

diff --git a/documentation/dev-portal/src/images/profile_picture/minibolt_pp.png b/documentation/dev-portal/src/images/profile_picture/minibolt_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..ed059e6055840dcd148f5760efc06b2eb5e331d9 GIT binary patch literal 13877 zcmV-5HpL{T8P z03<-{jo#49+uys(IcNU3_jNx24UhyHASv+_y889&#(npm@A>VUu-5Wpv-tYm={k2si~io&o;&+W=pG>U;=z7_;<7e;eS}xT+bTk6Z_~d%f174CpUpGW>0TFGH=L z%7CrBMfHMu2K4X0S*ZHW0Ps%WH-KN|$7_8id#*PWX!!=S;zxm#KZf9vJ=4kT8LK~O z06&tQ?7zp4|N48`vp({Zz@iUi^64&qGS{I@&v^F7k%E5%IQSC`F4?mm%=Y5PhJt_6 zsrC(}=Ic$tpCa}8ybbQg)ckn1M{h}h9|eBzEo{@?h*in<=+U
  • {J-bRK*gzt^>% zAobwY-pl}3-)70zESDeJOprH|MIXo%hPT1JHo5$4wwG@z3O0*GKt!d^0HdS}C}iow6NoV{%>A=?vuB8v*beqEJ}?Yq5iGi0okigc$f^d&$q% zg0U6>NGSlpz||0d82CT^{TY1kg8Q*+ca>d0^l#^qdld+>e>Y6=x)y*Reu;!jdn<_-DS1WVdi|D`Q-+^UP7V`N(hva1is5?waEBTk;$<# z#hk}bF_&I`5a5f!UAxbLyLrc;crqN0%LI&i0h-^%v4FZ9X0*RpDdfdLF%D(9;#)1I~ zp2R9aH`WkoBBMFq?y|Dd;rWwG7y(i^C?$vzgO#A9#9E290-uD3-!;K6fA|jW-M1A- z$@C!D6zfd4+wfV$s|)Buug83PJplg(@ISv>5JF%rB-&!K&xs;Kvlla0 z>+pkP=XvhrD#vD5IW@ORqZcA^)->)UNl@0Xz2fsXK7JRUc;77y6%bi^1$uWl=A*%#kj?yH6$7$ZArAv%p99iw-!W7U<{mZC7e9p zU}3q%>A4lY_rf`j&YZ{hEOFwHB$_0Na7sS!z2{aweD7}djFmZ8gKbsA-eHfCK+=jV zhZ~kdb2aXq8s%f#U-S0d{aRS{YX$g*u;we?NoK=Zn<`H)o><`bzI=$!Kk+gei%?*N zzzWH2JH~k6wkbYx_fBr#IYuGpAqLb}u>rV!_8Do*O2^QR4OkEcln{j4aIU9u6r61s zdfG?eP?3fQc34{7h(CPd7=QBJ7g(r8v^oaYw;&{O6ms+QG(YpP_p)dE5WN`om1A}m zB+bZjxBO~2E`s54z+dq4bm*?78 zYmo}_zQcoeZ0Doz*vr`R@D!lY!GX{Po9JN4qv4HF18oNa2()h)H2A?F&#a}oj6 zLPIS|AShDrK%Br_GeRlN?IUp4sA4$pa%Q28rSKiI|P!87^T3S%oh9%wLzQPbccf0?3gAzNhH9DCSE~KF|O9rRP{&4vCFm+end*-n)~(`N3PcW!vzDZo|~WkvcnU_WCj( z7i(Az;l*WGN)%FnqXk+^dRVlw7|)<$L93n6HI{~M~NV(nTN z3*bKcuZQsLB6K3?_F%HC$qPZGEsLFm`A$q2S@N#HcLZ%?sT%>Fj~`pSM9>6IuXgZr zmb;1-x}wKz!g0e}93v;4FF{3Kx<0g^b5@m-If|G5vcXZr}9c9)^yJX3j}@si?! z(W~0FU0kMu!g&?yz2R%ku_y#*7gzZo|DSL1wZjdpQoMh6k$>>B@8aFJ?YO{Ea51>_ zZOy);e*+(}u_?GmmZ9APo50@Dgke__Cx%APAgsnk;JTnBM2W@miwsGK;|`7+6HCdE zU&2*olEe}QKos!I%qlA#kEy9~e&weh;PYSoKDA~CC0#;oIQZ;wMk+oP>EdgL`9_2B z!qC-j+i!50tjNM&)AVXo7o>Iq~q;N@Bu=>?RF;IsphPK*0* z-^&ZH%yV{r32O}s$%!*_#P=Sc=)&&lBCpJJfc({N{iinKx*JjOHEGUKVsVr}idWZ^ zFV<}PaoTpL%cuVL$GB(z4*rL~b}xY+pkzv|v-5LI4d<|`ija`R7Hte(pwI)?y);$D z3~0|+N@OwXe`B+o(-tIr`4!7^XU;QT$}v%plsrKxr^p8iPbmx*-+|SxX1SZNTJPff zIXV%vW5bIlm-*e#eFY&MT;-5p`I&dz$*+F$9%jyVN#a#L{lL`K0=%I{z0s3Cd@Y)D zVp5;5-N13NQ7qS9tXu)garno-`XT<&C*Mmh$e~n9oyJ;98N=SR5>_H25<0e3e{D)m4=8Ijn_lY={$0 zxtwFy&Pl9^h?5X$HD{X*R@=~M)z~#!x)$kH$*|+q0KTRwxI|kLlSOvyMt)?w?!35! zdk6#q$8orO&*UXh7a;_tyi2X;kVL)pgCR4~fJI;s7XWqf2`x*_gi_w)*lZVT z(%`%`V1z-VF<4$-giKx@cyZy2Zfp@IjTq_lM6DmdfoF@grJGn*ItjB4&HXzId|+>Z zt<`{C+eXvP!)n)1^aLdrlmKZG3dMlsdWTB2h?EkE;o1{`n579{hTo9#&Bk}$JrL#xu=YEpwYE_cz=;Qri(1EHaM~H zgH#zrvb0pk7=slKo3I`k#L?M6{$4Y{uCi!rkyc>Eg@Jk7Kk1jIDsi-CI9HR*Hv|>m z;^#!F2}cm+6bmu=##2hHvN7X5ZBz7HqEnIm+xxhzfJY~R8s4N zz!3yW;AfUXqAiV{LBF9q~gQ5 zrsYTzic+wr6HkjB%MezQSk{pMK9D83wBLYPCw6NikIr! zVEsG1DCJgVU}`{SV#Hn`I{JU?3PawL6g-Ki1j0h7EzMZdi(|A%e_n|t(#dmr(I9%3 zUFAG8t4(g*K7#Tc>Wh}KVvcUJM-nI0x;?@urr>P~i|%823BV6;#+4hPMJhwyrrsKD zL1pr3wq<$p#4SXY1qV0CH_3xUC=;19@Ov34jf*02ReK*`q> zJcpbsab#)|F1IwZorLmKg-$m@<#Y7v9q7e~YCxoXI+0;=e2j8Q@bZyY7|soC26kM=B$VNVZ=eEzbQG+7B^#&VlDqjic~v3QIGlee|DIt)gkXx2t7b0 zv~3qR*J7vNrs_i}`x?y)90{&~z!41RCA)?k#*2b-&RH{0Mu$qw&MuII7OhkH->1_x zE@DzU+KTi`WYMPnSKqV}YbKLPLzS7CWUZwVK+c!AN|18|3c*SzAzu;9Ew7N6gq2zy zYr%6|{4%VfaLPWu6Y=803ge|AhI1a}z(ZypHe(F!FnYC=hu5lns-hl#Raiw`@>idM@~Z(4S_9-{@9vga^X4pNIi z3ak`#;snRpGzwnB)EQ8)Hf0@eYkJC|s}+7PrM!X*PaSXbjqkjSPn(~)yUNYOf-MC_ zb3_qoL8yI314+?ekM{H(2Yt=k&CHYGqCyIlYOVjALE8wnp45 zV9>~%i-}@LVk9n!Zs8-bZXRPJ3I#8d#}_FL*$K18Q1BIwk~sa61}X4;Nuy~80*}3ng#PLK=JZlw4z}+JLqehg4G?Bqk{# z=cTN9-PB4G)+Z+?IQ;TaX6NV0OP?@arPYea^9k&n} zMVJ64RbI5VBtnqrEc&yi@2(3GaY2FE#hxY*QlbRhvHzA7cOfuZqg1L$b-P`fnNX19`e1qslOE%gM1FHv2?wu)jXZ`e}uCP2>n1CD>9{Y#Vne2a3_6z>$L32#TKN=#pjB5u90!DUOOXB{w!KH@j%9aUB;W zB{|1sa|t-b)Y(k=3*Z@(YKcy2{+ypRJon0Jyo%!f17j%H<4i50;ub`7X^?i*~Ec^ww#>&BO3L*D$-%#b)A1NlD&w*jxfm<*>shH_Cjm-l8i5s-DaK z61=ed3SASiZF-0Y@7#*x#++-zu~m&tpzMpx0!_<66cD%)-vMm}j>@ttg_Kq8loU|P4 zN?M6vV$25t=i4D=FUNoS-Z26Z@{S!9_U)Wvv=nk;Q7~DsG+Krr2GlyJ$bsT*Az184 zrt_AXjcNBB?wx|IMJ|w?eFeJ{L(fPsmTr`W4h=BV44GSv>9%6562w;HN(TqY<`eLB zpy1UG{Ng?bVI6+!D|Ke(W+}OfJzFL@v?#f4B*GCEYb7-ebq!i4c-k`LN{TL&eM==L z$hiXJS)@!&qP_yAGq$|ivz%-gl4imO?{e@R1*|aa89I@sBm>Y;t84!GV~04me4gnk zhi#Q2`?P>0;ijn~=jtJWvh?DRKzRdR8@VP7jDU%P;9KVucT6ShDZ*qi4LW3*xdRD< zDNA2%S(JgRy>q)kdevQ zbm~P)-GpgqvDr(wxg6p89ySq_Du&U(up%JNK^()L@gm*O@?Q>~WamnWniw`~%ka6BKOVRWp>Pks1iZrL)z?|kJY?%6ZMyGDnRLX-2; zoGYmuz+MpIyf_p(wIg_dNpIH2@p?Aci8#FnLwVWkV7xY+>#qXn3&Lv4Nu zB?Tdt)c{7e__U16D@(~{1HAbx+VvEBMg$9U5w_XGRe3~t8x0%awj(|^r5N%Ir`v*D zULvjJ+>&Ost#MSsZ99f&)j>*^+2syDnh%+-I27D8G`Dv&$7IpsC|Ie-d}LbSN#B#FGG^a={3F2rkN#)g|l_b;iWWh>tsFQsW~XSmYvfs&mBL-k=Z$nv?Rtb zq+Q;(cZ|Rl)Fbb@C|R4jmW*Ut3F@;;#LX3Ksmzip@~^%NH&s1;YPaT|(SU7L!}n$* z=4&BA;IMtnBZ>nKK6jp^rx+df**RU{j+$7F^OUR+$^swIvhS)$8`jE>@J~XYWi4{5b0>GdVf7|a?u-E zrpZXrve<*6+`3MnO&aX)M25LKgj%wF)M2@+nJlN-pY0Vm_4F*IrlI3Wj1X)s6u5nQ zi1Rw3Yu!!PvNpZjtPR_ku*KoCGbAP^7dYH8k)vbb>#OkZe$?a0e9V+1`NTG#JGOY_ zJVDo3VykF$6WXEW+HXBvB?7dY`P5I)K%{|oM|qx8fvT+6!ShKBSmfwEH5kzW=)lIQ6p_;W+`IR1$5@-M9y!YQkIeGH+a~a&Pbf;%liCImB$Hh?HIqgI z$!J0F{8H+&^rXdFL6{h7orI;PVY!_!-!$Y3dA3$-e0*}4s_VlreD(_`IDX>Pnk&_J zUG{F@!s(hOOdNWxCNT8o26#&P^xSE>o$n(8kDXga@RUa{iP=%HL>-52Y?*7p=U<9= z|FpyVw>o_C)_^lDO&geSERB{WG0@fyC8gLuoK`EGU6R~1rYPs#O9KK@kPC7+P7a+I z9LHg4w#mv$ixZ1Ae*Jg;l7*fkR))#)Fs|p*La`Kd>2?Mc14<^9xJFD_tUOsN@ZRJuEO*aL^haI~w!*&qthT zT3jg@&qwSXi%5h6;m_q zL`~C|KI1IWu@K#lje>%NbbIAC&eI# z)&|#f@Z;`vVbPn~fcj%QN*sLp6%xmx=#)7yJ;t7@=12>MDKP4J%s0C9BEv*MGT%)2 z;X=Yp!!lJ8JiISvr4!RmBC5WRt1JaKZEe(QCET{vVY=)Mtk9hu?QQ`zq_&>Wd3?4lhb_l`dYemIJbuuxBx84X-h*v@Mer$!Gy` ztCsneWh`e16U+I!Ar8SQIgC~U_Brs)$WoV?yCaF!Rz9OJ^Fq^2#DTt8tW@rVJUwC+@$AT@yKk5ES!@p`xO& z=~fcYZn_Mv_z;^qfpjnmiuqI_*8iT?!(=FB<%O9^aK{ zV^Bh}+UZem3S_Q8oJ2%uT;Z%I>(LJ$SSlrlf*14HVa@IlSP4_gt@gmT&@z%zMY3aCb4F}RLoB=0a8L7W#fx`sb^He~0h>8 z=H}-K+%h*01st4BXt&xZ+%-=YS zbyRR-G2zAIOB{M}o@NpeON%QVk~n0nl;DwK*P+I2%5 zcG!}42OJx64cvaBe3BTBp0hl#A3m{7(TycUmd_sUa5{E*_zstMR3+b8hiMQil;~aaC$o zEQFSYE>r_a!Dwoo1jkj(t*-KAeBQOyVRUqaBePx3wCcQXv`WV8mi6W!LGRA0>%*e>DS1$`8h@y~fr5=Cq zqR+VNB8=pgDZz(!R*@RE`0#IEh-jWm@T6k8SU`~A`3^d9Y8V!`=P{`-$blQ~5B|5zhQd(55gex?{z{_V! zeBh>G&NQoRmln5Q9bpG7Nnz=A+uX9P%E%VU_hu40vEplI6?=x^{afLWUI{td2-)dc z#>)<-SfUgt&NsSPW4Uk7DF6D`K5=C);O2w8req!3%)G2&*FhNvAq`2h$@Y?EzNzRL zLD4mAuRtSASdKJqPGYs8)79i0pC}4h>B0+(hMWugMP>BSzh>~ON~vS-3!HQdc|tIkNic)?~{ zYYF27X(GruY%NQ2u4O2I<2B1lDA+#iv2VmO90>BBpix(-DB>4Cau2`$b9YhBduwI0 zc7yx94j`Wz1o-jIvW2A(OpbU6?VzM(vDL+uX%X2eZAmnEHcd3!QVsdnUy< z?is5vGk=PT7vMT-O+yzb9LGT?$r?z*fnaD7ZX1QgZt7 z4qSCQXnnN)mofeY%x7iB+Oe{ae4?OsnWH*EOCTosUv7= zOQ&b3b--7GZDmC_G$g)YBqwRKFTX8=?E2!e)jqfaL(+?Ac4Cebr1-=&jN1nc)E1~^%oD0o9by@Y}Xx9o|{xN2l96T?;9f+7)`Bu;o` zv4J&dW0Gnh=*G~B1VvYpcVQ?e**l~t`-&)mswXIUl8P@8)@8L9akj20x?*tZ#z5S5 zpjvDoO1sq}?DewiB!p2nz1Bu7 zR$O%M#0K?i;<}qeY=q??z+c#mD<4}Ckjt}cx(bfPV)(;vJV&Dw;i|NeNj(%u9JZGw zMOQFh5Zt}R<(*>^92c+HWv(MxXn__nCdhMe!QtdmR#~o1)<4>A%%=OTBCN%j2q_YT zh^fa3-Ij~z`}BGirNG!KQVgGmB~&W6;`M@y`b&}a#>hNNEqLOE*)@%{)=3lRM)Qh%MwNL-aM!qlFVo^` zR~e44N>(~9?I`B9Eg@S<9nd0`fi~@oV{JCvs^1JnK%xvdO_bZh@ifLHV0)ZAx5}2O zAtG&gX<3s~Fr-*(BQd!9LEw`lnlOxsBaN$Ej4>C2wAOUQu8D$~#Tv)YEt6=y?s2L*JA!YV zP9s4^Ktg%)&4oRG**+?n)(aSUZ+M|EQcb-3c zSpvQR+Vkl_rCDB%w69vhQZaECwr`!FR4pN0iBRypmuC6$_fMyCx1fn5=tODZuj`}$ zJ2K6d&_?m|xAvGU#hmX5Ryxq=IV`nvXgSbht1swG76B9yLN<|v2;(Ab36c2F_WAbA zFtwh~V=ow18j8GfX?88+#WYJ}BMP(DGCnrS{Nj0xG3&+SYiT@bY*zsP{=YoUr+(|3 zJbSW@6$)3WOW3lwF%~|`>q_|%Qf$s-MDOqXPh>|E9x@9m~!oj)4 z6@Klvzra8Hy=Pc%#`u9xVzYJ;_VR5Vuj6|3N&uhgyST2}2F}CwieSuz_wOGkkQOC0 z)>=-?hy2SwIZCUm2^B)pd=u|V7 zHvPi((;?G*Cle!+79>qxSq$m9lAE`8xqHtNvnJwHQ*-MU%TORmblM(ba0Fq$PPuOn zjSP>VLyd_Oj7|e7))@ZtH-5-3{cm6Avp)=p+#J$@o(6=>S{Z1W^yh;rHIj}Ae> zvyA#Nz60}3P$EGpiIVC9E5=p*tdI1Y)`qd+akSP%QNr`b&+$8d{sX@B;tC=e#zN*LYdBr?qLb)P4fJz5Xov(TxKB8}aZ*xrUCjWgjL>lA&CQhYsAtpFa6CT7!vN zB(dc)fBY@}yI;AVzp`iN1x>yCMO(gt;lSnoZI))w_G9;;q+070ZH!>D zC^*@(410oZ8@_s^$gMkDIHiEQwNEHKzP}ps@~md>P@d3%wuteR$9Uiqx|%J;gl(mO zZ_mT|sLZg?G-E>$c=#Ab1IbX)XEHA@3|I{Kw)=QIe`0|zeCHTn{N560>K%;q5K>@G zh!G)<6{PCD!Np0lJlFQauFo~LY5umje$-ogEdWD0;qvOo*jWf1kizobJwyDR4;|qD z_@i%Uh6^Yq3FDaG{?b9tudMRl|J4T=sTRSeHAht+CY=ObbTJmfPKWOwc9GWdqOs&1 z*jM%0c2mNSPC&s=`(PDvmSRq_TGzZ-3pmrU3{?f&be&f0aMyT_QD0MX(~OdwD;VtH zI~c66*7D?`6a4XaU*?<7EponL5W+zTfwWzWNHA!eOc@haBaw(CrkcA z+l$DWp6#qidXd4ppsG+bP!f`=?~o7DQ8uEN@W3v^@dbr)HTg)>@$(d1@O8xbreLY9 z**}%%xtWOZK(eC@d55)1z_ec$YZJj2Yi+*vgJXQ@sbl=$CUUD@=pIu}HB2IT4=JhjOG`5&KTxzWN{ zgB6lEiEuqZ*$*(?4j;XD2Ooc62Oqh655DKpNh~id#nihV8mL)|ZHL@3jKuL?L@CmPQ!RiBneCieae1k?g&W^t5K_rLuk9{bjd zBwFM63aJD-i7+~4d!A4zk03i612Jz-#Ss}R9L3biYS{H&r`hg(hTih$ZBJSGxPJrahJRmDB)mG7%9$UfSQ3OtOH&dZ+lF((NN8K4Eru_PBGW)(u;gNsVF%eunDtGLoIaZbt5|6E`be6lC+m~?3i@?4hcab zaIL~3No2}d61BED2$41&71lutfw4V2x6M!AyOqEF(fhdPruFG-mz$G#9Ra@P;go}c zh`U~w3?6uba}C2c7bQ#c4Th>^w&yi39XrGS_1M#_c3NpT&!pyruo8vB;Gm5`I5mVV zV&WpGE=WVy5d?`%dqxTer4^2_^o+)0Fgn4{xkOP5$5q6!pE$fyAJYqQwK!DYaH=zFT=KbaXK)omsnQXh9Mt@iVmyI9>4z=hxpfD zJqV$}7(pZzNwyUlgEcN#1wyBzbJnu$nqWIVl;fxG9^seXzmNSpC-Bz_&M%MX4T|?}`iS?}#j0OT=4_PD{KLaD zJodz4zWBrAG_@qunIFgs5+lgz_N?f3gFlGfwMX~f4< z3Qt(#u!k=N_wS$L1NUs>-M3G%XKD!FbzU=)Hvr(*#G0=b-~(B$|-AHElL5^b0 zv&ZK6>Y4_rBDKY>#actr zhx_)7@X(!GdEaeY**!f>sSsSEJiVq3y}sbq8JNd#JphJu2;%QuS;?{&XdU7;$fQ9~ zES81UHs3ou!}kx*^32imyt3G&7i)xYF(S#pb+Z)Q1U(QawpOlPONwwQY6b!bC3q!HxuA1Iza5DPTdXX_ipF} zSj%l%-zp)X(GGdx_<5c=wulB++BIgE&U0=N&Me2Y;|Oa~c5bZ2b6tu#hw0%WyCzF) zsTL^&4mnRTQ4V;=%@a(Gm$Dv{muJ0~z2_@LhOQ&PS9EA>Ho#=8`oYUm@T)o5FD^qE z7+BetqgUFjFbaucO|z@%C5A+&^+diSQ|c2?3|z{2AK4$kk+BqU@huIONNnIYwyy!$ z>kRM{TxD1OYXP{Lfqd6StaoiVbGB(>gWnDQ9UvV}piF*t!M$Dp_tzt&uC=$7uPZB4pXMq&RBx0F-e?^l^`E{i zmoJsKpJKDySlvJh9@MZ8kj60IUg`Qx2F9>o&vhdx_-$&w!Bl&rDR?7l{`)^+vbml; z^MM-)?i&Gce?3Z??)j6TY5#WitdG7CA1>d(2d`z?<1W(Diyyc3ne5pfxgO@vn^gv1 zY3FS$+6+fEk8K>S1H}qx#xWB5TQItpCLdw{o4A?Kck<|KD0r+C7ek23@ z%@%V$&3du?sWmi7MwP=T{1g(n1<00000NkvXXu0mjf DYWw7D literal 0 HcmV?d00001 diff --git a/documentation/dev-portal/theme/css/general.css b/documentation/dev-portal/theme/css/general.css index a06db43965..84dbfa3371 100644 --- a/documentation/dev-portal/theme/css/general.css +++ b/documentation/dev-portal/theme/css/general.css @@ -62,7 +62,8 @@ h3:target::before, h4:target::before, h5:target::before, h6:target::before { - display: inline-block; + /* display "none" in order to avoid default artifacts on the community-applications-and-guides page */ + display: none; content: "»"; margin-left: -30px; width: 30px; From 4631c72c6b093c45dcf9b6e0c18e93b67194bba0 Mon Sep 17 00:00:00 2001 From: Lorexia Date: Thu, 13 Jul 2023 10:36:27 +0200 Subject: [PATCH 11/59] Update quickstart overview, delete project comments in community-applications-and-guides --- .../community-applications-and-guides.md | 31 ++++++------------- .../dev-portal/src/quickstart/overview.md | 4 ++- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md index 78e0916d4f..ba00922658 100644 --- a/documentation/dev-portal/src/community-resources/community-applications-and-guides.md +++ b/documentation/dev-portal/src/community-resources/community-applications-and-guides.md @@ -2,7 +2,7 @@ We love seeing our developer community create applications using Nym. If you would like to share your application with the community, please submit a pull request to the `main` branch of the `nymtech/dev-portal` [repository](https://github.com/nymtech/dev-portal). - + ## Pastenym @@ -11,9 +11,8 @@ We love seeing our developer community create applications using Nym. If you wou * [Github](https://github.com/notrustverify/pastenym) * [Deployed App](https://pastenym.ch) - - + ## Nostr-Nym @@ -23,19 +22,16 @@ We love seeing our developer community create applications using Nym. If you wou * [Deployed App](https://nostrnym.pnproxy.org/) * [Documentation](https://blog.notrustverify.ch/nostr-relay-on-nym) - - ## Spook > Ethereum RPC request mixer uses the Nym network mixing service to anonymize RPC requests to the Ethereum network without revealing sensitive data and metadata. * [Github](https://github.com/EdenBlockVC/spook) - - + ## Ethereum Transaction Broadcaster @@ -43,9 +39,8 @@ We love seeing our developer community create applications using Nym. If you wou * [Github](https://github.com/noot/nym-ethtx) - - + ## NymDrive @@ -54,28 +49,24 @@ We love seeing our developer community create applications using Nym. If you wou * [Demo](https://www.youtube.com/watch?v=5Rx73nw8NYI) * [Presentation](https://docs.google.com/presentation/d/1MpvIK32Mx9VKLVfMTcvbeyrsKHHUsTvDQ-3n31dR0NE/edit#slide=id.p) - - + ## Nym Dashboard > Developed by No Trust Verify, this dashboard is a great tool to get information about the mixnet, gateways and mixnodes. * [Deployed App](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) - - - + ## Is Nym Up > Explore whether we're up through IsNymUp, a tool that helps check the heath of the Nym network as well as some mixnet related statistics! * [Deployed App](https://isnymup.com/) - - + ## DarkFi over Nym @@ -83,18 +74,16 @@ We love seeing our developer community create applications using Nym. If you wou * [Github](https://github.com/darkrenaissance/darkfi) * [Documentation](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html) - - + ## Nymstr email > Experience secure and private email communication with ease using Nymstr email, which enables seamless transmission of emails over a SOCKS5 proxy and our NYM mixnet! * [Github](https://github.com/dial0ut/nymstr-email) - - + ## Minibolt @@ -102,7 +91,6 @@ We love seeing our developer community create applications using Nym. If you wou * [Github](https://github.com/minibolt-guide/minibolt) * [Documentation](https://v2.minibolt.info/bonus-guides/system/nym-mixnet#proxying-bitcoin-core) -

    @@ -118,6 +106,7 @@ We aren't the only ones writing documentation: the Nym developer community is al * [Awesome Nym list](https://notrustverify.github.io/awesome-nym/) ([GitHub](https://github.com/notrustverify/awesome-nym)) * A lot of guides can be found on the [NTV Blog](https://blog.notrustverify.ch/) + ## The Way of the NYMJA by Pineapple Proxy🍍 diff --git a/documentation/dev-portal/src/quickstart/overview.md b/documentation/dev-portal/src/quickstart/overview.md index 50a6d4187b..b2ac4199c9 100644 --- a/documentation/dev-portal/src/quickstart/overview.md +++ b/documentation/dev-portal/src/quickstart/overview.md @@ -2,9 +2,11 @@ There are multiple options to quickly connect to Nym and see the network in action without the need for any code changes to your application. At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet. -Demo application: +Demo applications: * a browser-based 'hello world' [chat application](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet! * a Coconut-scheme based [Credential Library](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials! +
    +Proxy traffic with the Nym Socks5 client: * set up a plug-and-play connection with the [NymConnect](./nymconnect-gui.md) GUI for proxying Telegram, Electrum, Keybase or Blockstream Green traffic through the mixnet (~2 minutes). * [Download and run](./socks-proxy.md) the Nym Socks5 client via the CLI, for other desktop applications with SOCKS5 connection options (~30 minutes). From 6d79b6f6005dbc9c5d339aeb3ca08bcd12cb1624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Thu, 13 Jul 2023 11:40:40 +0300 Subject: [PATCH 12/59] Apply clippy fix (#3670) --- contracts/multisig/cw4-group/src/contract.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/multisig/cw4-group/src/contract.rs b/contracts/multisig/cw4-group/src/contract.rs index 543388c6fa..c141210507 100644 --- a/contracts/multisig/cw4-group/src/contract.rs +++ b/contracts/multisig/cw4-group/src/contract.rs @@ -288,7 +288,7 @@ mod tests { // this is only valid if we are not doing a historical query if height.is_none() { // compute expected metrics - let weights = vec![user1_weight, user2_weight, user3_weight]; + let weights = [user1_weight, user2_weight, user3_weight]; let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); let count = weights.iter().filter(|x| x.is_some()).count(); @@ -495,7 +495,7 @@ mod tests { let add_msg2 = ExecuteMsg::AddHook { addr: contract2.clone(), }; - for msg in vec![add_msg, add_msg2] { + for msg in [add_msg, add_msg2] { let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); } From 110b4d384e412bfc32b848214cfb33564560e162 Mon Sep 17 00:00:00 2001 From: wigy <1888808+wigy-opensource-developer@users.noreply.github.com> Date: Mon, 17 Jul 2023 11:29:28 +0200 Subject: [PATCH 13/59] fix: typo in Rust SDK docs (#3655) --- documentation/docs/src/sdk/rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/sdk/rust.md b/documentation/docs/src/sdk/rust.md index ba1c079725..9e60d40efd 100644 --- a/documentation/docs/src/sdk/rust.md +++ b/documentation/docs/src/sdk/rust.md @@ -102,4 +102,4 @@ The following code shows how you can use the SDK to create and use a [credential {{#include ../../../../sdk/rust/nym-sdk/examples/bandwidth.rs}} ``` -You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](../cococnut.md). +You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](../coconut.md). From d7b53cba40d2dd7a8b68f8741c958a817cbb3ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 17 Jul 2023 10:19:53 +0100 Subject: [PATCH 14/59] don't send funds for pledge decrease simulation --- nym-wallet/src-tauri/src/operations/simulate/mixnet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs index 0f12ff80c4..19bfe80970 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs @@ -128,7 +128,7 @@ pub async fn simulate_update_pledge( .attempt_convert_to_base_coin(dec_delta.clone())? .into(), }, - Some(dec_delta), + None, &state, ) .await From f8943eebceba1561867df4257a9882f76e4aa9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 17 Jul 2023 10:26:32 +0100 Subject: [PATCH 15/59] preemptively resolving future clippy issue --- nym-wallet/src-tauri/src/operations/simulate/mixnet.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs index 19bfe80970..332f0eeb43 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs @@ -124,9 +124,7 @@ pub async fn simulate_update_pledge( ); simulate_mixnet_operation( ExecuteMsg::DecreasePledge { - decrease_by: guard - .attempt_convert_to_base_coin(dec_delta.clone())? - .into(), + decrease_by: guard.attempt_convert_to_base_coin(dec_delta)?.into(), }, None, &state, From 9a51135d224e13aeafd196966d6c4cfbd83fee66 Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 18 Jul 2023 10:43:27 +0200 Subject: [PATCH 16/59] debugging --- .github/workflows/nym-wallet-publish-ubuntu.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 5cfe79df98..80607a2358 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -61,6 +61,13 @@ jobs: TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: nym-wallet_1.0.0_amd64.AppImage.tar.gz + path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz + retention-days: 30 + - id: create-release name: Upload to release based on tag name uses: softprops/action-gh-release@v1 @@ -70,6 +77,15 @@ jobs: nym-wallet/target/release/bundle/appimage/*.AppImage nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz* + - name: Debug + run: | + semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}" + echo "${{ github.ref_name }}" + echo "${${{ github.ref_name }}##nym-wallet-}" + echo "version=$semver" + echo "filename=nym-wallet_$version_amd64.AppImage" + echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" + - id: release-info name: Prepare release info run: | From 1fafc126fbae6a06dcd74d2affdffc15299553a9 Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 18 Jul 2023 11:06:45 +0200 Subject: [PATCH 17/59] debugging --- .github/workflows/nym-wallet-publish-ubuntu.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 80607a2358..1dd673130c 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -79,12 +79,14 @@ jobs: - name: Debug run: | - semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}" - echo "${{ github.ref_name }}" - echo "${${{ github.ref_name }}##nym-wallet-}" - echo "version=$semver" - echo "filename=nym-wallet_$version_amd64.AppImage" - echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" + ref=${{ github.ref_name }} + semver="${ref##nym-wallet-}" && semver="${semver##v}" + echo "$ref" + echo "${ref##nym-wallet-}" + echo "${semver}" + version="${semver}" + echo "nym-wallet_${version}_amd64.AppImage" + echo "${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" - id: release-info name: Prepare release info From 41e1009095c811bd381be0166e13de3c791e4c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Tue, 18 Jul 2023 12:15:20 +0300 Subject: [PATCH 18/59] Upgrade cosmwasm (#3678) * Upgrade cosmwasm * Remove serde annotation for Denom too * Fix clippy after rustup update --- Cargo.lock | 268 ++-- Cargo.toml | 24 +- clients/webassembly/Cargo.lock | 268 ++-- clients/webassembly/src/client/config.rs | 2 +- .../client-libs/validator-client/Cargo.toml | 4 +- .../validator-client/src/nyxd/fee/mod.rs | 37 +- .../validator-client/src/nyxd/mod.rs | 2 +- common/commands/Cargo.toml | 4 +- .../validator/cosmwasm/generators/multisig.rs | 2 + .../coconut-bandwidth-contract/src/msg.rs | 2 +- .../src/spend_credential.rs | 8 +- .../contracts-common/src/signing/mod.rs | 2 +- .../group-contract/Cargo.toml | 2 + .../group-contract/src/msg.rs | 30 +- .../mixnet-contract/src/delegation.rs | 10 +- .../mixnet-contract/src/gateway.rs | 8 +- .../mixnet-contract/src/interval.rs | 4 +- .../mixnet-contract/src/mixnode.rs | 18 +- .../mixnet-contract/src/pending_events.rs | 12 +- .../mixnet-contract/src/rewarding/mod.rs | 4 +- .../mixnet-contract/src/types.rs | 6 +- .../multisig-contract/Cargo.toml | 2 + .../multisig-contract/src/error.rs | 12 +- .../multisig-contract/src/lib.rs | 1 + .../multisig-contract/src/msg.rs | 45 +- .../multisig-contract/src/state.rs | 59 + .../vesting-contract/src/lib.rs | 6 +- .../vesting-contract/src/messages.rs | 2 +- common/credentials/Cargo.toml | 2 +- common/ledger/Cargo.toml | 4 +- common/types/Cargo.toml | 2 +- contracts/Cargo.lock | 280 ++-- contracts/Cargo.toml | 27 +- .../src/verification_key_shares/storage.rs | 2 +- contracts/coconut-test/src/helpers.rs | 2 +- .../src/spend_credential_creates_proposal.rs | 2 + .../src/submit_vk_creates_proposal.rs | 2 + contracts/mixnet/src/delegations/queries.rs | 2 +- contracts/mixnet/src/delegations/storage.rs | 4 +- contracts/mixnet/src/mixnodes/storage.rs | 4 +- contracts/mixnet/src/rewards/transactions.rs | 4 +- contracts/mixnet/src/support/helpers.rs | 4 +- .../multisig/cw3-flex-multisig/Cargo.toml | 11 +- .../cw3-flex-multisig/src/contract.rs | 1250 +++++++++++++++-- .../multisig/cw3-flex-multisig/src/lib.rs | 25 +- .../multisig/cw3-flex-multisig/src/state.rs | 20 - contracts/multisig/cw4-group/.cargo/config | 6 +- contracts/multisig/cw4-group/Cargo.toml | 10 +- contracts/multisig/cw4-group/src/contract.rs | 399 +----- contracts/multisig/cw4-group/src/error.rs | 14 +- contracts/multisig/cw4-group/src/helpers.rs | 20 +- contracts/multisig/cw4-group/src/lib.rs | 19 + contracts/multisig/cw4-group/src/state.rs | 24 +- contracts/multisig/cw4-group/src/tests.rs | 439 ++++++ contracts/name-service/src/state/names.rs | 4 +- .../src/state/services.rs | 4 +- contracts/vesting/src/vesting/account/mod.rs | 2 +- explorer-api/src/mix_node/models.rs | 2 +- integrations/bity/Cargo.toml | 4 +- nym-api/nym-api-requests/Cargo.toml | 2 +- nym-api/src/coconut/tests.rs | 4 + nym-connect/desktop/Cargo.lock | 272 ++-- nym-wallet/Cargo.lock | 323 +++-- nym-wallet/Cargo.toml | 2 +- nym-wallet/nym-wallet-types/Cargo.toml | 2 +- nym-wallet/src-tauri/Cargo.toml | 4 +- 66 files changed, 2856 insertions(+), 1191 deletions(-) create mode 100644 common/cosmwasm-smart-contracts/multisig-contract/src/state.rs delete mode 100644 contracts/multisig/cw3-flex-multisig/src/state.rs create mode 100644 contracts/multisig/cw4-group/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 6d8e1dadd7..967762ef02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,18 +400,18 @@ dependencies = [ [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -495,7 +495,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -508,12 +507,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -883,9 +876,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" @@ -929,8 +922,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost 0.10.4", "prost-types 0.10.1", @@ -939,8 +933,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -961,11 +956,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.1" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -974,26 +969,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -1176,9 +1198,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1310,10 +1332,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1324,9 +1347,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1335,22 +1358,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1358,11 +1385,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1370,11 +1398,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1441,11 +1485,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1577,9 +1633,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1635,16 +1691,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1832,6 +1890,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "figment" version = "0.10.8" @@ -2216,6 +2284,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -2891,15 +2970,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] @@ -3903,6 +3981,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3941,7 +4021,7 @@ dependencies = [ "rand_chacha 0.3.1", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time 0.3.21", @@ -4027,7 +4107,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -5002,11 +5084,11 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -5154,13 +5236,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -5781,12 +5862,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -5805,6 +5886,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -6139,10 +6229,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -6230,6 +6321,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.5.0" @@ -6376,14 +6476,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -6427,11 +6525,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -6534,9 +6632,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -6903,9 +7001,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -6934,9 +7032,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -6948,9 +7046,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -6966,9 +7064,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 4f0e80d599..8e40379227 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,19 +117,21 @@ anyhow = "1.0.71" async-trait = "0.1.64" bip39 = { version = "2.0.0", features = ["zeroize"] } cfg-if = "1.0.0" -cosmwasm-derive = "=1.0.0" -cosmwasm-schema = "=1.0.0" -cosmwasm-std = "=1.0.0" -cosmwasm-storage = "=1.0.0" -cw-controllers = "=0.13.4" -cw-storage-plus = "=0.13.4" -cw-utils = "=0.13.4" -cw2 = { version = "=0.13.4" } -cw3 = { version = "=0.13.4" } -cw3-fixed-multisig = { version = "=0.13.4" } -cw4 = { version = "=0.13.4" } +cosmwasm-derive = "=1.2.5" +cosmwasm-schema = "=1.2.5" +cosmwasm-std = "=1.2.5" +cosmwasm-storage = "=1.2.5" +cosmrs = "=0.8.0" +cw-utils = "=1.0.1" +cw-storage-plus = "=1.0.1" +cw2 = { version = "=1.0.1" } +cw3 = { version = "=1.0.1" } +cw3-fixed-multisig = { version = "=1.0.1" } +cw4 = { version = "=1.0.1" } +cw-controllers = { version = "=1.0.1" } dotenvy = "0.15.6" generic-array = "0.14.7" +k256 = "0.11" getrandom = "0.2.10" lazy_static = "1.4.0" log = "0.4" diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 823fbbb252..ceef50ba14 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -237,18 +237,18 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -332,7 +332,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -345,12 +344,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -577,9 +570,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "constant_time_eq" @@ -605,8 +598,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -615,8 +609,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -637,11 +632,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa" +checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -650,26 +645,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -783,9 +805,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -867,10 +889,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -881,9 +904,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -892,22 +915,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -915,11 +942,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -927,11 +955,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -953,11 +997,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1050,9 +1106,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1108,16 +1164,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1232,6 +1290,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "flate2" version = "1.0.26" @@ -1524,6 +1592,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -1978,15 +2057,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] @@ -2540,6 +2618,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -2556,7 +2636,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -2566,7 +2646,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -3085,11 +3167,11 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -3214,13 +3296,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -3549,12 +3630,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -3573,6 +3654,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -3742,10 +3832,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -3818,6 +3909,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.5.0" @@ -3953,14 +4053,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -3974,11 +4072,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -4048,9 +4146,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -4335,9 +4433,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -4366,9 +4464,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -4380,9 +4478,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -4398,9 +4496,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index e531f072d1..07d9ab5f5f 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -4,7 +4,7 @@ // due to expansion of #[wasm_bindgen] macro on `Debug` Config struct #![allow(clippy::drop_non_drop)] // another issue due to #[wasm_bindgen] and `Copy` trait -#![allow(clippy::drop_copy)] +#![allow(dropping_copy_types)] use nym_client_core::config::{ Acknowledgements as ConfigAcknowledgements, Config as BaseClientConfig, diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 3e0428e643..ac66916c46 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -41,7 +41,7 @@ nym-api-requests = { path = "../../../nym-api/nym-api-requests" } async-trait = { workspace = true, optional = true } bip39 = { workspace = true, features = ["rand"], optional = true } nym-config = { path = "../../config", optional = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"], optional = true } +cosmrs = { workspace = true, features = ["rpc", "bip32", "cosmwasm"], optional = true } # note that this has the same version as used by cosmrs eyre = { version = "0.6", optional = true } cw3 = { workspace = true, optional = true } @@ -55,7 +55,7 @@ cosmwasm-std = { workspace = true, optional = true } [dev-dependencies] bip39 = { workspace = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32"] } +cosmrs = { workspace = true, features = ["rpc", "bip32"] } tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } ts-rs = "6.1.2" diff --git a/common/client-libs/validator-client/src/nyxd/fee/mod.rs b/common/client-libs/validator-client/src/nyxd/fee/mod.rs index e1ee4b4d5c..6b857f8a66 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/mod.rs @@ -127,46 +127,13 @@ impl GasAdjustable for Gas { mod sealed { use cosmrs::tx::{self, Gas}; use cosmrs::Coin as CosmosCoin; - use cosmrs::{AccountId, Decimal as CosmosDecimal, Denom as CosmosDenom}; + use cosmrs::{AccountId, Denom as CosmosDenom}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - fn cosmos_denom_inner_getter(val: &CosmosDenom) -> String { - val.as_ref().to_string() - } - - #[derive(Serialize, Deserialize)] - #[serde(remote = "CosmosDenom")] - struct Denom(#[serde(getter = "cosmos_denom_inner_getter")] String); - - impl From for CosmosDenom { - fn from(val: Denom) -> Self { - val.0.parse().unwrap() - } - } - - fn cosmos_decimal_inner_getter(val: &CosmosDecimal) -> u64 { - // haha, this code is so disgusting. I'll make a PR on cosmrs to slightly alleviate those issues... - // note: unwrap here is fine as the to_string is just returning a stringified u64 which, well, is a valid u64 - val.to_string().parse().unwrap() - } - - // at the time of writing it the current cosmrs' Decimal is extremely limited... - #[derive(Serialize, Deserialize)] - #[serde(remote = "CosmosDecimal")] - struct Decimal(#[serde(getter = "cosmos_decimal_inner_getter")] u64); - - impl From for CosmosDecimal { - fn from(val: Decimal) -> Self { - val.0.into() - } - } - #[derive(Serialize, Deserialize, Clone)] struct Coin { - #[serde(with = "Denom")] denom: CosmosDenom, - #[serde(with = "Decimal")] - amount: CosmosDecimal, + amount: u128, } impl From for CosmosCoin { diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 58890e8621..0d90eb2387 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -39,7 +39,7 @@ pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo; pub use cosmrs::tendermint::Time as TendermintTime; pub use cosmrs::tx::{self, Gas}; pub use cosmrs::Coin as CosmosCoin; -pub use cosmrs::{bip32, AccountId, Decimal, Denom}; +pub use cosmrs::{bip32, AccountId, Denom}; use cosmwasm_std::Addr; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 9f77a9e4ae..d57e1c47ac 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -14,7 +14,7 @@ clap = { version = "4.0", features = ["derive"] } cw-utils = { workspace = true } handlebars = "3.0.1" humantime-serde = "1.0" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { workspace = true, features = ["ecdsa", "sha256"] } log = { workspace = true } rand = {version = "0.6", features = ["std"] } serde = { version = "1.0", features = ["derive"] } @@ -25,7 +25,7 @@ toml = "0.5.6" url = "2.2" tap = "1" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } cosmwasm-std = { workspace = true } nym-validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] } diff --git a/common/commands/src/validator/cosmwasm/generators/multisig.rs b/common/commands/src/validator/cosmwasm/generators/multisig.rs index cb610845c6..37f05a5e71 100644 --- a/common/commands/src/validator/cosmwasm/generators/multisig.rs +++ b/common/commands/src/validator/cosmwasm/generators/multisig.rs @@ -56,6 +56,8 @@ pub async fn generate(args: Args) { .expect("threshold can't be converted to Decimal"), }, max_voting_period: Duration::Time(args.max_voting_period), + executor: None, + proposal_deposit: None, coconut_bandwidth_contract_address: coconut_bandwidth_contract_address.to_string(), coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(), }; diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs index 20f1e2700d..8fffcc81eb 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/msg.rs @@ -14,7 +14,7 @@ pub struct InstantiateMsg { pub mix_denom: String, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { DepositFunds { data: DepositData }, diff --git a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs index ffece73fd4..7cb47dc73b 100644 --- a/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs +++ b/common/cosmwasm-smart-contracts/coconut-bandwidth-contract/src/spend_credential.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::msg::ExecuteMsg; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct SpendCredentialData { funds: Coin, blinded_serial_number: String, @@ -43,7 +43,7 @@ pub enum SpendCredentialStatus { Spent, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct SpendCredential { funds: Coin, blinded_serial_number: String, @@ -74,7 +74,7 @@ impl SpendCredential { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedSpendCredentialResponse { pub spend_credentials: Vec, pub per_page: usize, @@ -95,7 +95,7 @@ impl PagedSpendCredentialResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct SpendCredentialResponse { pub spend_credential: Option, } diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs b/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs index 206152957b..23018c9249 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/signing/mod.rs @@ -15,7 +15,7 @@ pub type Nonce = u32; // define this type explicitly for [hopefully] better usability // (so you wouldn't need to worry about whether you should use bytes, bs58, etc.) -#[derive(Clone, Debug, PartialEq, JsonSchema)] +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct MessageSignature(Vec); impl MessageSignature { diff --git a/common/cosmwasm-smart-contracts/group-contract/Cargo.toml b/common/cosmwasm-smart-contracts/group-contract/Cargo.toml index 9f57c84154..2856c44925 100644 --- a/common/cosmwasm-smart-contracts/group-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/group-contract/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cosmwasm-schema = { workspace = true } cw4 = { workspace = true } +cw-controllers = { workspace = true } schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs index a5a473135d..3f95227492 100644 --- a/common/cosmwasm-smart-contracts/group-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/group-contract/src/msg.rs @@ -1,13 +1,7 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::{cw_serde, QueryResponses}; use cw4::Member; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub struct InstantiateMsg { /// The admin is the only account that can update the group state. /// Omit it to make the group immutable. @@ -15,8 +9,7 @@ pub struct InstantiateMsg { pub members: Vec, } -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { /// Change the admin UpdateAdmin { admin: Option }, @@ -32,23 +25,24 @@ pub enum ExecuteMsg { RemoveHook { addr: String }, } -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return AdminResponse + #[returns(cw_controllers::AdminResponse)] Admin {}, - /// Return TotalWeightResponse - TotalWeight {}, - /// Returns MembersListResponse + #[returns(cw4::TotalWeightResponse)] + TotalWeight { at_height: Option }, + #[returns(cw4::MemberListResponse)] ListMembers { start_after: Option, limit: Option, }, - /// Returns MemberResponse + #[returns(cw4::MemberResponse)] Member { addr: String, at_height: Option, }, - /// Shows all registered hooks. Returns HooksResponse. + /// Shows all registered hooks. + #[returns(cw_controllers::HooksResponse)] Hooks {}, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs index 876ce7b515..55294498b8 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/delegation.rs @@ -37,7 +37,7 @@ pub fn generate_owner_storage_subkey( } } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct Delegation { /// Address of the owner of this delegation. pub owner: Addr, @@ -114,7 +114,7 @@ impl Delegation { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixNodeDelegationsResponse { pub delegations: Vec, pub start_next_after: Option, @@ -129,7 +129,7 @@ impl PagedMixNodeDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedDelegatorDelegationsResponse { pub delegations: Vec, pub start_next_after: Option<(MixId, OwnerProxySubKey)>, @@ -147,7 +147,7 @@ impl PagedDelegatorDelegationsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeDelegationResponse { pub delegation: Option, pub mixnode_still_bonded: bool, @@ -162,7 +162,7 @@ impl MixNodeDelegationResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedAllDelegationsResponse { pub delegations: Vec, pub start_next_after: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs index 5d39b2c150..c312d42bf7 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/gateway.rs @@ -23,7 +23,7 @@ pub struct Gateway { pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayBond { pub pledge_amount: Coin, pub owner: Addr, @@ -132,7 +132,7 @@ impl GatewayConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedGatewayResponse { pub nodes: Vec, pub per_page: usize, @@ -153,13 +153,13 @@ impl PagedGatewayResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayOwnershipResponse { pub address: Addr, pub gateway: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct GatewayBondResponse { pub identity: IdentityKey, pub gateway: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index fc2b14d71e..5afdbd827e 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs @@ -489,7 +489,7 @@ impl CurrentIntervalResponse { } } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct PendingEpochEventsResponse { pub seconds_until_executable: i64, pub events: Vec, @@ -510,7 +510,7 @@ impl PendingEpochEventsResponse { } } -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct PendingIntervalEventsResponse { pub seconds_until_executable: i64, pub events: Vec, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 6d5ca55e7b..69f1a89209 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -33,7 +33,7 @@ impl RewardedSetNodeStatus { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeDetails { pub bond_information: MixNodeBond, pub rewarding_details: MixNodeRewarding, @@ -86,7 +86,7 @@ impl MixNodeDetails { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeRewarding { /// Information provided by the operator that influence the cost function. pub cost_params: MixNodeCostParams, @@ -465,7 +465,7 @@ impl MixNodeRewarding { } // operator information + data assigned by the contract(s) -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeBond { /// Unique id assigned to the bonded mixnode. pub mix_id: MixId, @@ -559,7 +559,7 @@ pub struct MixNode { pub version: String, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixNodeCostParams { pub profit_margin_percent: Percent, @@ -686,7 +686,7 @@ impl MixNodeConfigUpdate { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixnodeBondsResponse { pub nodes: Vec, pub per_page: usize, @@ -703,7 +703,7 @@ impl PagedMixnodeBondsResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct PagedMixnodesDetailsResponse { pub nodes: Vec, pub per_page: usize, @@ -745,19 +745,19 @@ impl PagedUnbondedMixnodesResponse { } } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixOwnershipResponse { pub address: Addr, pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixnodeDetailsResponse { pub mix_id: MixId, pub mixnode_details: Option, } -#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)] pub struct MixnodeRewardingDetailsResponse { pub mix_id: MixId, pub rewarding_details: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs index 886c5b46b1..5f4db1ab90 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/pending_events.rs @@ -7,19 +7,19 @@ use crate::{BlockHeight, EpochEventId, IntervalEventId, MixId}; use cosmwasm_std::{Addr, Coin}; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingEpochEvent { pub id: EpochEventId, pub event: PendingEpochEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingEpochEventData { pub created_at: BlockHeight, pub kind: PendingEpochEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum PendingEpochEventKind { // can't just pass the `Delegation` struct here as it's impossible to determine // `cumulative_reward_ratio` ahead of time @@ -68,19 +68,19 @@ impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent { } } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingIntervalEvent { pub id: IntervalEventId, pub event: PendingIntervalEventData, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct PendingIntervalEventData { pub created_at: BlockHeight, pub kind: PendingIntervalEventKind, } -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] pub enum PendingIntervalEventKind { ChangeMixCostParams { mix_id: MixId, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs index ee091e6b13..650e39a2ff 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/mod.rs @@ -35,7 +35,7 @@ pub struct RewardDistribution { pub delegates: Decimal, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] pub struct PendingRewardResponse { pub amount_staked: Option, pub amount_earned: Option, @@ -46,7 +46,7 @@ pub struct PendingRewardResponse { pub mixnode_still_fully_bonded: bool, } -#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)] pub struct EstimatedCurrentEpochRewardResponse { pub original_stake: Option, diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs index e1df97f04a..e0a8109f98 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs @@ -22,7 +22,7 @@ pub type EpochEventId = u32; pub type IntervalEventId = u32; #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq, Eq)] pub struct LayerAssignment { mix_id: MixId, layer: Layer, @@ -118,7 +118,7 @@ impl Index for LayerDistribution { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractState { pub owner: Addr, // only the owner account can update state pub rewarding_validator_address: Addr, @@ -130,7 +130,7 @@ pub struct ContractState { pub params: ContractStateParams, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractStateParams { /// Minimum amount a delegator must stake in orders for his delegation to get accepted. pub minimum_mixnode_delegation: Option, diff --git a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml index 4688654e1b..2a6753267e 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml +++ b/common/cosmwasm-smart-contracts/multisig-contract/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" cw-utils = { workspace = true } cw3 = { workspace = true } cw4 = { workspace= true } +cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs index b10fa6b506..ead941cad0 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/error.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use cosmwasm_std::StdError; -use cw_utils::ThresholdError; +use cw3::DepositError; +use cw_utils::{PaymentError, ThresholdError}; use thiserror::Error; @@ -17,9 +18,6 @@ pub enum ContractError { #[error("Group contract invalid address '{addr}'")] InvalidGroup { addr: String }, - #[error("Coconut bandwidth contract address not found")] - InvalidCoconutBandwidth {}, - #[error("Unauthorized")] Unauthorized {}, @@ -43,4 +41,10 @@ pub enum ContractError { #[error("Cannot close completed or passed proposals")] WrongCloseStatus {}, + + #[error("{0}")] + Payment(#[from] PaymentError), + + #[error("{0}")] + Deposit(#[from] DepositError), } diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs index a968ed14e5..64af48ecf9 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/lib.rs @@ -1,2 +1,3 @@ pub mod error; pub mod msg; +pub mod state; diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs index db37835f64..15b959fa14 100644 --- a/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/msg.rs @@ -1,15 +1,15 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - +use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{CosmosMsg, Empty}; -use cw3::Vote; +use cw3::{UncheckedDepositInfo, Vote}; use cw4::MemberChangedHookMsg; use cw_utils::{Duration, Expiration, Threshold}; -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] +use crate::state::Executor; + +#[cw_serde] pub struct InstantiateMsg { // this is the group contract that contains the member list pub group_addr: String, @@ -17,11 +17,15 @@ pub struct InstantiateMsg { pub coconut_dkg_contract_address: String, pub threshold: Threshold, pub max_voting_period: Duration, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, + /// The cost of creating a proposal (if any). + pub proposal_deposit: Option, } // TODO: add some T variants? Maybe good enough as fixed Empty for now -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Propose { title: String, @@ -45,41 +49,44 @@ pub enum ExecuteMsg { } // We can also add this as a cw3 extension -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { - /// Return ThresholdResponse + #[returns(cw_utils::ThresholdResponse)] Threshold {}, - /// Returns ProposalResponse + #[returns(cw3::ProposalResponse)] Proposal { proposal_id: u64 }, - /// Returns ProposalListResponse + #[returns(cw3::ProposalListResponse)] ListProposals { start_after: Option, limit: Option, }, - /// Returns ProposalListResponse + #[returns(cw3::ProposalListResponse)] ReverseProposals { start_before: Option, limit: Option, }, - /// Returns VoteResponse + #[returns(cw3::VoteResponse)] Vote { proposal_id: u64, voter: String }, - /// Returns VoteListResponse + #[returns(cw3::VoteListResponse)] ListVotes { proposal_id: u64, start_after: Option, limit: Option, }, - /// Returns VoterInfo + #[returns(cw3::VoterResponse)] Voter { address: String }, - /// Returns VoterListResponse + #[returns(cw3::VoterListResponse)] ListVoters { start_after: Option, limit: Option, }, + /// Gets the current configuration. + #[returns(crate::state::Config)] + Config {}, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] + +#[cw_serde] pub struct MigrateMsg { pub coconut_bandwidth_address: String, pub coconut_dkg_address: String, diff --git a/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs b/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs new file mode 100644 index 0000000000..d3ce181ba1 --- /dev/null +++ b/common/cosmwasm-smart-contracts/multisig-contract/src/state.rs @@ -0,0 +1,59 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, QuerierWrapper}; +use cw3::DepositInfo; +use cw4::Cw4Contract; +use cw_storage_plus::Item; +use cw_utils::{Duration, Threshold}; + +use crate::error::ContractError; + +/// Defines who is able to execute proposals once passed +#[cw_serde] +pub enum Executor { + /// Any member of the voting group, even with 0 points + Member, + /// Only the given address + Only(Addr), +} + +#[cw_serde] +pub struct Config { + pub threshold: Threshold, + pub max_voting_period: Duration, + // Total weight and voters are queried from this contract + pub group_addr: Cw4Contract, + pub coconut_bandwidth_addr: Addr, + pub coconut_dkg_addr: Addr, + // who is able to execute passed proposals + // None means that anyone can execute + pub executor: Option, + /// The price, if any, of creating a new proposal. + pub proposal_deposit: Option, +} + +impl Config { + // Executor can be set in 3 ways: + // - Member: any member of the voting group is authorized + // - Only: only passed address is authorized + // - None: Everyone are authorized + pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> { + if let Some(executor) = &self.executor { + match executor { + Executor::Member => { + self.group_addr + .is_member(querier, sender, None)? + .ok_or(ContractError::Unauthorized {})?; + } + Executor::Only(addr) => { + if addr != sender { + return Err(ContractError::Unauthorized {}); + } + } + } + } + Ok(()) + } +} + +// unique items +pub const CONFIG: Item = Item::new("config"); diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs index 75d916ddad..6c456674a5 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/lib.rs @@ -28,7 +28,7 @@ pub enum Period { After, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct PledgeData { pub amount: Coin, pub block_time: Timestamp, @@ -49,7 +49,7 @@ impl PledgeData { } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub enum PledgeCap { Percent(Percent), Absolute(Uint128), // This has to be in unym @@ -77,7 +77,7 @@ impl Default for PledgeCap { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct OriginalVestingResponse { pub amount: Coin, pub number_of_periods: usize, diff --git a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs index 226f39a9c0..f4d7147e2c 100644 --- a/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs +++ b/common/cosmwasm-smart-contracts/vesting-contract/src/messages.rs @@ -55,7 +55,7 @@ impl VestingSpecification { } } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ExecuteMsg { // Families diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 3f029494dd..6bb10d5cb6 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } thiserror = "1.0" # I guess temporarily until we get serde support in coconut up and running diff --git a/common/ledger/Cargo.toml b/common/ledger/Cargo.toml index 9bea382a73..dda242bf14 100644 --- a/common/ledger/Cargo.toml +++ b/common/ledger/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bip32 = "0.3.0" -k256 = "0.10.4" +bip32 = "0.4.0" +k256 = { workspace = true } ledger-transport = "0.10.0" ledger-transport-hid = "0.10.0" thiserror = "1" \ No newline at end of file diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index 2c106260c2..0dd4879310 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -20,7 +20,7 @@ url = "2.2" ts-rs = "6.1.2" cosmwasm-std = { workspace = true } -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ "nyxd-client", diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 1db4c0bd8a..0c3efd0a24 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -50,9 +50,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "autocfg" @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", "arrayvec", @@ -260,23 +260,23 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -285,45 +285,62 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" dependencies = [ + "cosmwasm-schema-derive", "schemars", + "serde", "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] [[package]] name = "cosmwasm-storage" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" +checksum = "a3737a3aac48f5ed883b5b73bfb731e77feebd8fc6b43419844ec2971072164d" dependencies = [ "cosmwasm-std", "serde", @@ -361,9 +378,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", @@ -374,9 +391,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -389,9 +406,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.6", "rand_core 0.6.4", @@ -454,10 +471,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -468,17 +486,17 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.13.4" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f9a8ab7c3c29ec93cb7a39ce4b14a05e053153b4a17ef7cf2246af1b7c087e" +checksum = "2a18afd2e201221c6d72a57f0886ef2a22151bbc9e6db7af276fde8a91081042" dependencies = [ "anyhow", "cosmwasm-std", - "cosmwasm-storage", "cw-storage-plus", "cw-utils", "derivative", "itertools", + "k256", "prost", "schemars", "serde", @@ -487,9 +505,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -498,22 +516,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -521,11 +543,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -533,11 +556,45 @@ dependencies = [ ] [[package]] -name = "cw3-fixed-multisig" -version = "0.13.4" +name = "cw20-base" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54aa54c13f405ec4ab36b6217538bc957d439eee58f89312db05a79caf6706" +checksum = "afcd279230b08ed8afd8be5828221622bd5b9ce25d0b01d58bad626c6ce0169c" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "cw2", + "cw20", + "schemars", + "semver", + "serde", + "thiserror", +] + +[[package]] +name = "cw3" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw3-fixed-multisig" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e2415adb201e5e89dab34edf59d7dc166bc558526de009a49ae66276c9119a" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -550,14 +607,15 @@ dependencies = [ [[package]] name = "cw3-flex-multisig" -version = "0.13.1" +version = "1.0.0" dependencies = [ - "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus", "cw-utils", "cw2", + "cw20", + "cw20-base", "cw3", "cw3-fixed-multisig", "cw4", @@ -565,15 +623,15 @@ dependencies = [ "nym-group-contract-common", "nym-multisig-contract-common", "schemars", - "serde", ] [[package]] name = "cw4" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -582,7 +640,7 @@ dependencies = [ [[package]] name = "cw4-group" -version = "0.13.4" +version = "1.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -599,11 +657,12 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", ] [[package]] @@ -654,9 +713,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -683,7 +742,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -698,7 +757,7 @@ dependencies = [ "hex", "rand_core 0.6.4", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -710,16 +769,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", + "digest 0.10.7", "ff", "generic-array 0.14.6", "group", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -778,9 +839,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" dependencies = [ "rand_core 0.6.4", "subtle 2.4.1", @@ -974,9 +1035,9 @@ dependencies = [ [[package]] name = "group" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff", "rand_core 0.6.4", @@ -992,15 +1053,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.1" @@ -1020,7 +1072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest 0.9.0", - "hmac", + "hmac 0.11.0", ] [[package]] @@ -1033,6 +1085,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "humantime" version = "2.1.0" @@ -1083,7 +1144,7 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -1123,15 +1184,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2", + "sha2 0.10.6", ] [[package]] @@ -1217,9 +1277,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -1252,11 +1312,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1347,6 +1407,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -1387,7 +1449,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -1397,7 +1459,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -1595,13 +1659,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -1827,12 +1890,12 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -1941,10 +2004,11 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.6", "pkcs8", @@ -1976,6 +2040,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.160" @@ -2034,12 +2107,23 @@ dependencies = [ ] [[package]] -name = "signature" -version = "1.4.0" +name = "sha2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "digest 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -2067,20 +2151,20 @@ dependencies = [ "curve25519-dalek", "digest 0.9.0", "hkdf", - "hmac", + "hmac 0.11.0", "lioness", "log", "rand 0.7.3", "rand_distr", - "sha2", + "sha2 0.9.9", "subtle 2.4.1", ] [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 9d1fb0ac6a..1b20380ad7 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -32,16 +32,17 @@ incremental = false overflow-checks = true [workspace.dependencies] -cosmwasm-crypto = "=1.0.0" -cosmwasm-derive = "=1.0.0" -cosmwasm-schema = "=1.0.0" -cosmwasm-std = "=1.0.0" -cosmwasm-storage = "=1.0.0" -cw-controllers = "=0.13.4" -cw-multi-test = "=0.13.4" -cw-storage-plus = "=0.13.4" -cw-utils = "=0.13.4" -cw2 = "=0.13.4" -cw3 = "=0.13.4" -cw3-fixed-multisig = "=0.13.4" -cw4 = "=0.13.4" +cosmwasm-crypto = "=1.2.5" +cosmwasm-derive = "=1.2.5" +cosmwasm-schema = "=1.2.5" +cosmwasm-std = "=1.2.5" +cosmwasm-storage = "=1.2.5" +cw-controllers = "=1.0.1" +cw-multi-test = "=0.16.4" +cw-storage-plus = "=1.0.1" +cw-utils = "=1.0.1" +cw2 = "=1.0.1" +cw3 = "=1.0.1" +cw3-fixed-multisig = "=1.0.1" +cw4 = "=1.0.1" +cw20 = "=1.0.1" diff --git a/contracts/coconut-dkg/src/verification_key_shares/storage.rs b/contracts/coconut-dkg/src/verification_key_shares/storage.rs index fae9a59d10..51a7fbb03e 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/storage.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/storage.rs @@ -30,7 +30,7 @@ impl<'a> IndexList for VkShareIndex<'a> { pub(crate) fn vk_shares<'a>() -> IndexedMap<'a, VKShareKey<'a>, ContractVKShare, VkShareIndex<'a>> { let indexes = VkShareIndex { epoch_id: MultiIndex::new( - |d| d.epoch_id, + |_pk, d| d.epoch_id, VK_SHARES_PK_NAMESPACE, VK_SHARES_EPOCH_ID_IDX_NAMESPACE, ), diff --git a/contracts/coconut-test/src/helpers.rs b/contracts/coconut-test/src/helpers.rs index c679176177..e0f667612d 100644 --- a/contracts/coconut-test/src/helpers.rs +++ b/contracts/coconut-test/src/helpers.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use cosmwasm_std::{entry_point, Addr, Coin, DepsMut, Empty, Env, Response}; -use cw3_flex_multisig::state::CONFIG; use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper}; use nym_multisig_contract_common::error::ContractError; +use nym_multisig_contract_common::state::CONFIG; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/contracts/coconut-test/src/spend_credential_creates_proposal.rs b/contracts/coconut-test/src/spend_credential_creates_proposal.rs index 317f28a024..abcf761da5 100644 --- a/contracts/coconut-test/src/spend_credential_creates_proposal.rs +++ b/contracts/coconut-test/src/spend_credential_creates_proposal.rs @@ -45,6 +45,8 @@ fn spend_credential_creates_proposal() { threshold: Threshold::AbsolutePercentage { percentage: Decimal::from_ratio(2u128, 3u128), }, + executor: None, + proposal_deposit: None, max_voting_period: Duration::Height(1000), coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), diff --git a/contracts/coconut-test/src/submit_vk_creates_proposal.rs b/contracts/coconut-test/src/submit_vk_creates_proposal.rs index d111b1f0c7..4e1d5dc346 100644 --- a/contracts/coconut-test/src/submit_vk_creates_proposal.rs +++ b/contracts/coconut-test/src/submit_vk_creates_proposal.rs @@ -52,6 +52,8 @@ fn dkg_proposal() { threshold: Threshold::AbsolutePercentage { percentage: Decimal::from_ratio(1u128, 1u128), }, + executor: None, + proposal_deposit: None, max_voting_period: Duration::Time(1000), coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), diff --git a/contracts/mixnet/src/delegations/queries.rs b/contracts/mixnet/src/delegations/queries.rs index 0de9d151cf..5a5d07c32f 100644 --- a/contracts/mixnet/src/delegations/queries.rs +++ b/contracts/mixnet/src/delegations/queries.rs @@ -520,7 +520,7 @@ mod tests { .delegations .iter() .filter(|d| d.proxy.is_some()) - .all(|d| d.proxy.as_ref().unwrap() == &vesting_contract)); + .all(|d| d.proxy.as_ref().unwrap() == vesting_contract)); // now make sure that if we do it in paged manner, we'll get exactly the same result let per_page = Some(15); diff --git a/contracts/mixnet/src/delegations/storage.rs b/contracts/mixnet/src/delegations/storage.rs index b74bb870b0..5d3e6b45f2 100644 --- a/contracts/mixnet/src/delegations/storage.rs +++ b/contracts/mixnet/src/delegations/storage.rs @@ -27,12 +27,12 @@ impl<'a> IndexList for DelegationIndex<'a> { pub(crate) fn delegations<'a>() -> IndexedMap<'a, PrimaryKey, Delegation, DelegationIndex<'a>> { let indexes = DelegationIndex { owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), DELEGATION_PK_NAMESPACE, DELEGATION_OWNER_IDX_NAMESPACE, ), mixnode: MultiIndex::new( - |d| d.mix_id, + |_pk, d| d.mix_id, DELEGATION_PK_NAMESPACE, DELEGATION_MIXNODE_IDX_NAMESPACE, ), diff --git a/contracts/mixnet/src/mixnodes/storage.rs b/contracts/mixnet/src/mixnodes/storage.rs index fdf744e0bd..2007456463 100644 --- a/contracts/mixnet/src/mixnodes/storage.rs +++ b/contracts/mixnet/src/mixnodes/storage.rs @@ -39,12 +39,12 @@ pub(crate) fn unbonded_mixnodes<'a>( ) -> IndexedMap<'a, MixId, UnbondedMixnode, UnbondedMixnodeIndex<'a>> { let indexes = UnbondedMixnodeIndex { owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), UNBONDED_MIXNODES_PK_NAMESPACE, UNBONDED_MIXNODES_OWNER_IDX_NAMESPACE, ), identity_key: MultiIndex::new( - |d| d.identity_key.clone(), + |_pk, d| d.identity_key.clone(), UNBONDED_MIXNODES_PK_NAMESPACE, UNBONDED_MIXNODES_IDENTITY_IDX_NAMESPACE, ), diff --git a/contracts/mixnet/src/rewards/transactions.rs b/contracts/mixnet/src/rewards/transactions.rs index b73c66a499..19ca0e8c83 100644 --- a/contracts/mixnet/src/rewards/transactions.rs +++ b/contracts/mixnet/src/rewards/transactions.rs @@ -185,7 +185,7 @@ pub(crate) fn _try_withdraw_operator_reward( // we can only attempt to send the message to the vesting contract if the proxy IS the vesting contract // otherwise, we don't care let vesting_contract = mixnet_params_storage::vesting_contract_address(deps.storage)?; - if proxy == &vesting_contract { + if proxy == vesting_contract { let msg = VestingContractExecuteMsg::TrackReward { amount: reward.clone(), address: owner.clone().into_string(), @@ -271,7 +271,7 @@ pub(crate) fn _try_withdraw_delegator_reward( // we can only attempt to send the message to the vesting contract if the proxy IS the vesting contract // otherwise, we don't care let vesting_contract = mixnet_params_storage::vesting_contract_address(deps.storage)?; - if proxy == &vesting_contract { + if proxy == vesting_contract { let msg = VestingContractExecuteMsg::TrackReward { amount: reward.clone(), address: owner.clone().into_string(), diff --git a/contracts/mixnet/src/support/helpers.rs b/contracts/mixnet/src/support/helpers.rs index e39541f599..094d96eaba 100644 --- a/contracts/mixnet/src/support/helpers.rs +++ b/contracts/mixnet/src/support/helpers.rs @@ -298,7 +298,7 @@ pub(crate) fn ensure_is_authorized( sender: &Addr, storage: &dyn Storage, ) -> Result<(), MixnetContractError> { - if sender != &crate::mixnet_contract_settings::storage::rewarding_validator_address(storage)? { + if sender != crate::mixnet_contract_settings::storage::rewarding_validator_address(storage)? { return Err(MixnetContractError::Unauthorized); } Ok(()) @@ -309,7 +309,7 @@ pub(crate) fn ensure_can_advance_epoch( storage: &dyn Storage, ) -> Result { let epoch_status = crate::interval::storage::current_epoch_status(storage)?; - if sender != &epoch_status.being_advanced_by { + if sender != epoch_status.being_advanced_by { // well, we know we're going to throw an error now, // but we might as well also check if we're even a validator // to return a possibly better error message diff --git a/contracts/multisig/cw3-flex-multisig/Cargo.toml b/contracts/multisig/cw3-flex-multisig/Cargo.toml index 0c45bb149d..b849828069 100644 --- a/contracts/multisig/cw3-flex-multisig/Cargo.toml +++ b/contracts/multisig/cw3-flex-multisig/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "cw3-flex-multisig" -version = "0.13.1" +version = "1.0.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Implementing cw3 with multiple voting patterns and dynamic groups" license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" @@ -13,6 +13,7 @@ documentation = "https://docs.cosmwasm.com" crate-type = ["cdylib", "rlib"] [features] +backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] @@ -22,15 +23,15 @@ cw2 = { workspace = true } cw3 = { workspace = true } cw3-fixed-multisig = { workspace = true, features = ["library"] } cw4 = { workspace = true } +cw20 = { workspace = true } cw-storage-plus = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8.1" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" } nym-multisig-contract-common = { path= "../../../common/cosmwasm-smart-contracts/multisig-contract" } [dev-dependencies] -cosmwasm-schema = { version = "1.0.0" } -cw4-group = { path = "../cw4-group", version = "0.13.4" } +cw4-group = { path = "../cw4-group", version = "1.0.0" } cw-multi-test = { workspace = true } +cw20-base = "1.0.0" diff --git a/contracts/multisig/cw3-flex-multisig/src/contract.rs b/contracts/multisig/cw3-flex-multisig/src/contract.rs index 24c460b0a2..9a0c8eacad 100644 --- a/contracts/multisig/cw3-flex-multisig/src/contract.rs +++ b/contracts/multisig/cw3-flex-multisig/src/contract.rs @@ -8,18 +8,19 @@ use cosmwasm_std::{ }; use cw2::set_contract_version; + use cw3::{ - ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, VoteListResponse, VoteResponse, - VoterDetail, VoterListResponse, VoterResponse, + Ballot, Proposal, ProposalListResponse, ProposalResponse, Status, Vote, VoteInfo, + VoteListResponse, VoteResponse, VoterDetail, VoterListResponse, VoterResponse, Votes, }; -use cw3_fixed_multisig::state::{next_id, Ballot, Proposal, Votes, BALLOTS, PROPOSALS}; +use cw3_fixed_multisig::state::{next_id, BALLOTS, PROPOSALS}; use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff}; use cw_storage_plus::Bound; use cw_utils::{maybe_addr, Expiration, ThresholdResponse}; -use crate::state::{Config, CONFIG}; use nym_multisig_contract_common::error::ContractError; use nym_multisig_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use nym_multisig_contract_common::state::{Config, CONFIG}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:cw3-flex-multisig"; @@ -46,6 +47,11 @@ pub fn instantiate( let total_weight = group_addr.total_weight(&deps.querier)?; msg.threshold.validate(total_weight)?; + let proposal_deposit = msg + .proposal_deposit + .map(|deposit| deposit.into_checked(deps.as_ref())) + .transpose()?; + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let cfg = Config { @@ -54,21 +60,14 @@ pub fn instantiate( group_addr, coconut_bandwidth_addr, coconut_dkg_addr, + executor: msg.executor, + proposal_deposit, }; CONFIG.save(deps.storage, &cfg)?; Ok(Response::default()) } -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result { - let mut cfg = CONFIG.load(deps.storage)?; - cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?; - cfg.coconut_dkg_addr = deps.api.addr_validate(&msg.coconut_dkg_address)?; - CONFIG.save(deps.storage, &cfg)?; - Ok(Default::default()) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, @@ -105,6 +104,11 @@ pub fn execute_propose( // only members of the multisig can create a proposal let cfg = CONFIG.load(deps.storage)?; + // Check that the native deposit was paid (as needed). + if let Some(deposit) = cfg.proposal_deposit.as_ref() { + deposit.check_native_deposit_paid(&info)?; + } + // Only the coconut bandwidth or dkg contracts can create proposals if info.sender != cfg.coconut_bandwidth_addr && info.sender != cfg.coconut_dkg_addr { return Err(ContractError::Unauthorized {}); @@ -122,6 +126,15 @@ pub fn execute_propose( return Err(ContractError::WrongExpiration {}); } + // Take the cw20 token deposit, if required. We do this before + // creating the proposal struct below so that we can avoid a clone + // and move the loaded deposit info into it. + let take_deposit_msg = if let Some(deposit_info) = cfg.proposal_deposit.as_ref() { + deposit_info.get_take_deposit_messages(&info.sender, &env.contract.address)? + } else { + vec![] + }; + // create a proposal let mut prop = Proposal { title, @@ -133,6 +146,8 @@ pub fn execute_propose( votes: Votes::yes(vote_power), threshold: cfg.threshold, total_weight: cfg.group_addr.total_weight(&deps.querier)?, + proposer: info.sender.clone(), + deposit: cfg.proposal_deposit, }; prop.update_status(&env.block); let id = next_id(deps.storage)?; @@ -146,6 +161,7 @@ pub fn execute_propose( BALLOTS.save(deps.storage, (id, &info.sender), &ballot)?; Ok(Response::new() + .add_messages(take_deposit_msg) .add_attribute("action", "propose") .add_attribute("sender", info.sender) .add_attribute("proposal_id", id.to_string()) @@ -164,9 +180,11 @@ pub fn execute_vote( // ensure proposal exists and can be voted on let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if prop.status != Status::Open { + // Allow voting on Passed and Rejected proposals too, + if ![Status::Open, Status::Passed, Status::Rejected].contains(&prop.status) { return Err(ContractError::NotOpen {}); } + // if they are not expired if prop.expires.is_expired(&env.block) { return Err(ContractError::Expired {}); } @@ -206,21 +224,31 @@ pub fn execute_execute( info: MessageInfo, proposal_id: u64, ) -> Result { - // anyone can trigger this if the vote passed - let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; // we allow execution even after the proposal "expiration" as long as all vote come in before // that point. If it was approved on time, it can be executed any time. - if prop.current_status(&env.block) != Status::Passed { + prop.update_status(&env.block); + if prop.status != Status::Passed { return Err(ContractError::WrongExecuteStatus {}); } + let cfg = CONFIG.load(deps.storage)?; + cfg.authorize(&deps.querier, &info.sender)?; + // set it to executed prop.status = Status::Executed; PROPOSALS.save(deps.storage, proposal_id, &prop)?; + // Unconditionally refund here. + let response = match prop.deposit { + Some(deposit) => { + Response::new().add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + None => Response::new(), + }; + // dispatch all proposed messages - Ok(Response::new() + Ok(response .add_messages(prop.msgs) .add_attribute("action", "execute") .add_attribute("sender", info.sender) @@ -236,10 +264,11 @@ pub fn execute_close( // anyone can trigger this if the vote passed let mut prop = PROPOSALS.load(deps.storage, proposal_id)?; - if [Status::Executed, Status::Rejected, Status::Passed] - .iter() - .any(|x| *x == prop.status) - { + if [Status::Executed, Status::Rejected, Status::Passed].contains(&prop.status) { + return Err(ContractError::WrongCloseStatus {}); + } + // Avoid closing of Passed due to expiration proposals + if prop.current_status(&env.block) == Status::Passed { return Err(ContractError::WrongCloseStatus {}); } if !prop.expires.is_expired(&env.block) { @@ -250,7 +279,15 @@ pub fn execute_close( prop.status = Status::Rejected; PROPOSALS.save(deps.storage, proposal_id, &prop)?; - Ok(Response::new() + // Refund the deposit if we have been configured to do so. + let mut response = Response::new(); + if let Some(deposit) = prop.deposit { + if deposit.refund_failed_proposals { + response = response.add_message(deposit.get_return_deposit_message(&prop.proposer)?) + } + } + + Ok(response .add_attribute("action", "close") .add_attribute("sender", info.sender) .add_attribute("proposal_id", proposal_id.to_string())) @@ -294,6 +331,7 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { QueryMsg::ListVoters { start_after, limit } => { to_binary(&list_voters(deps, start_after, limit)?) } + QueryMsg::Config {} => to_binary(&query_config(deps)?), } } @@ -303,6 +341,10 @@ fn query_threshold(deps: Deps) -> StdResult { Ok(cfg.threshold.to_response(total_weight)) } +fn query_config(deps: Deps) -> StdResult { + CONFIG.load(deps.storage) +} + fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult { let prop = PROPOSALS.load(deps.storage, id)?; let status = prop.current_status(&env.block); @@ -314,6 +356,8 @@ fn query_proposal(deps: Deps, env: Env, id: u64) -> StdResult msgs: prop.msgs, status, expires: prop.expires, + proposer: prop.proposer, + deposit: prop.deposit, threshold, }) } @@ -370,6 +414,8 @@ fn map_proposal( msgs: prop.msgs, status, expires: prop.expires, + deposit: prop.deposit, + proposer: prop.proposer, threshold, } }) @@ -440,15 +486,26 @@ fn list_voters( Ok(VoterListResponse { voters }) } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result { + let mut cfg = CONFIG.load(deps.storage)?; + cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?; + cfg.coconut_dkg_addr = deps.api.addr_validate(&msg.coconut_dkg_address)?; + CONFIG.save(deps.storage, &cfg)?; + Ok(Default::default()) +} + #[cfg(test)] mod tests { - use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp}; + use cosmwasm_std::{coin, coins, Addr, BankMsg, Coin, Decimal, Timestamp, Uint128}; use cw2::{query_contract_info, ContractVersion}; + use cw20::{Cw20Coin, UncheckedDenom}; + use cw3::{DepositError, UncheckedDepositInfo}; use cw4::{Cw4ExecuteMsg, Member}; use cw4_group::helpers::Cw4GroupContract; use cw_multi_test::{ - next_block, App, AppBuilder, AppResponse, Contract, ContractWrapper, Executor, + next_block, App, AppBuilder, BankSudo, Contract, ContractWrapper, Executor, SudoMsg, }; use cw_utils::{Duration, Threshold}; @@ -461,9 +518,8 @@ mod tests { const VOTER4: &str = "voter0004"; const VOTER5: &str = "voter0005"; const SOMEBODY: &str = "somebody"; - const TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = - "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; - const TEST_COCONUT_DKG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; + const BANDWIDTH_CONTRACT: &str = "coconut_bandwidth_addr"; + const DKG_CONTRACT: &str = "coconut_dkg_addr"; fn member>(addr: T, weight: u64) -> Member { Member { @@ -490,6 +546,15 @@ mod tests { Box::new(contract) } + fn contract_cw20() -> Box> { + let contract = ContractWrapper::new( + cw20_base::contract::execute, + cw20_base::contract::instantiate, + cw20_base::contract::query, + ); + Box::new(contract) + } + fn mock_app(init_funds: &[Coin]) -> App { AppBuilder::new().build(|router, _, storage| { router @@ -510,40 +575,27 @@ mod tests { .unwrap() } - fn propose_and_vote( - app: &mut App, - flex_addr: Addr, - proposal: ExecuteMsg, - voter: &str, - ) -> AppResponse { - let proposer = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - let res = app - .execute_contract(Addr::unchecked(proposer), flex_addr.clone(), &proposal, &[]) - .unwrap(); - - let yes_vote = ExecuteMsg::Vote { - proposal_id: res.custom_attrs(1)[2].value.parse().unwrap(), - vote: Vote::Yes, - }; - let _ = app.execute_contract(Addr::unchecked(voter), flex_addr, &yes_vote, &[]); - - res - } - + #[allow(clippy::too_many_arguments)] #[track_caller] fn instantiate_flex( app: &mut App, group: Addr, + coconut_bandwidth_contract_address: Addr, + coconut_dkg_contract_address: Addr, threshold: Threshold, max_voting_period: Duration, + executor: Option, + proposal_deposit: Option, ) -> Addr { let flex_id = app.store_code(contract_flex()); let msg = InstantiateMsg { group_addr: group.to_string(), + coconut_bandwidth_contract_address: coconut_bandwidth_contract_address.to_string(), + coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(), threshold, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor, + proposal_deposit, }; app.instantiate_contract(flex_id, Addr::unchecked(OWNER), &msg, &[], "flex", None) .unwrap() @@ -568,6 +620,8 @@ mod tests { max_voting_period, init_funds, multisig_as_group_admin, + None, + None, ) } @@ -578,11 +632,11 @@ mod tests { max_voting_period: Duration, init_funds: Vec, multisig_as_group_admin: bool, + executor: Option, + proposal_deposit: Option, ) -> (Addr, Addr) { - let coconut_bandwidth_contract = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - // 1. Instantiate group contract with members (and OWNER as admin) and coconut bandwidth contract + // 1. Instantiate group contract with members (and OWNER as admin) let members = vec![ - member(coconut_bandwidth_contract, 0), member(OWNER, 0), member(VOTER1, 1), member(VOTER2, 2), @@ -594,7 +648,16 @@ mod tests { app.update_block(next_block); // 2. Set up Multisig backed by this group - let flex_addr = instantiate_flex(app, group_addr.clone(), threshold, max_voting_period); + let flex_addr = instantiate_flex( + app, + group_addr.clone(), + Addr::unchecked(BANDWIDTH_CONTRACT), + Addr::unchecked(DKG_CONTRACT), + threshold, + max_voting_period, + executor, + proposal_deposit, + ); app.update_block(next_block); // 3. (Optional) Set the multisig as the group owner @@ -641,6 +704,16 @@ mod tests { } } + fn text_proposal() -> ExecuteMsg { + let (_, title, description) = proposal_info(); + ExecuteMsg::Propose { + title, + description, + msgs: vec![], + latest: None, + } + } + #[test] fn test_instantiate_works() { let mut app = mock_app(&[]); @@ -654,13 +727,15 @@ mod tests { // Zero required weight fails let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::ThresholdQuorum { threshold: Decimal::zero(), quorum: Decimal::percent(1), }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -680,10 +755,12 @@ mod tests { // Total weight less than required weight not allowed let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::AbsoluteCount { weight: 100 }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let err = app .instantiate_contract( @@ -703,10 +780,12 @@ mod tests { // All valid let instantiate_msg = InstantiateMsg { group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), threshold: Threshold::AbsoluteCount { weight: 1 }, max_voting_period, - coconut_bandwidth_contract_address: TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(), - coconut_dkg_contract_address: TEST_COCONUT_DKG_CONTRACT_ADDRESS.to_string(), + executor: None, + proposal_deposit: None, }; let flex_addr = app .instantiate_contract( @@ -720,7 +799,7 @@ mod tests { .unwrap(); // Verify contract version set properly - let version = query_contract_info(&app, flex_addr.clone()).unwrap(); + let version = query_contract_info(&app.wrap(), flex_addr.clone()).unwrap(); assert_eq!( ContractVersion { contract: CONTRACT_NAME.to_string(), @@ -760,7 +839,7 @@ mod tests { setup_test_case_fixed(&mut app, required_weight, voting_period, init_funds, false); let proposal = pay_somebody_proposal(); - // Only voters can propose + // Only special addresses can propose let err = app .execute_contract(Addr::unchecked(SOMEBODY), flex_addr.clone(), &proposal, &[]) .unwrap_err(); @@ -779,13 +858,44 @@ mod tests { }; let err = app .execute_contract( - Addr::unchecked(TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string()), - flex_addr, + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), &proposal_wrong_exp, &[], ) .unwrap_err(); assert_eq!(ContractError::WrongExpiration {}, err.downcast().unwrap()); + + // Proposal from special address works + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "propose"), + ("sender", BANDWIDTH_CONTRACT), + ("proposal_id", "1"), + ("status", "Open"), + ], + ); + let res = app + .execute_contract(Addr::unchecked(DKG_CONTRACT), flex_addr, &proposal, &[]) + .unwrap(); + assert_eq!( + res.custom_attrs(1), + [ + ("action", "propose"), + ("sender", DKG_CONTRACT), + ("proposal_id", "2"), + ("status", "Open"), + ], + ); } fn get_tally(app: &App, flex_addr: &str, proposal_id: u64) -> u64 { @@ -826,49 +936,6 @@ mod tests { } } - #[test] - fn test_proposer_limited_to_coconut_bandwidth() { - let init_funds = coins(10, "BTC"); - let mut app = mock_app(&init_funds); - - let voting_period = Duration::Time(2000000); - let threshold = Threshold::ThresholdQuorum { - threshold: Decimal::percent(80), - quorum: Decimal::percent(20), - }; - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); - let proposal = pay_somebody_proposal(); - - let err = app - .execute_contract(Addr::unchecked(OWNER), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let err = app - .execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let err = app - .execute_contract(Addr::unchecked(SOMEBODY), flex_addr.clone(), &proposal, &[]) - .unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); - - let proposer = TEST_COCONUT_BANDWIDTH_CONTRACT_ADDRESS.to_string(); - let res = app - .execute_contract(Addr::unchecked(&proposer), flex_addr, &proposal, &[]) - .unwrap(); - assert_eq!( - res.custom_attrs(1), - [ - ("action", "propose"), - ("sender", &proposer), - ("proposal_id", "1"), - ("status", "Open"), - ], - ); - } - #[test] fn test_proposal_queries() { let init_funds = coins(10, "BTC"); @@ -879,26 +946,73 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }; - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 1 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id1: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id1, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // another proposal immediately passes app.update_block(next_block); let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER4); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // expire them both app.update_block(expire(voting_period)); // add one more open proposal, 2 votes let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER2); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); let proposal_id3: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id3, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER2), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let proposed_at = app.block_info(); // next block, let's query them all... make sure status is properly updated (1 should be rejected in query) @@ -954,6 +1068,8 @@ mod tests { threshold: Decimal::percent(80), quorum: Decimal::percent(20), }, + proposer: Addr::unchecked(BANDWIDTH_CONTRACT), + deposit: None, }; assert_eq!(&expected, &res.proposals[0]); } @@ -968,11 +1084,26 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1066,13 +1197,38 @@ mod tests { ], ); - // non-Open proposals cannot be voted - let err = app + // Passed proposals can still be voted (while they are not expired or executed) + let res = app .execute_contract(Addr::unchecked(VOTER5), flex_addr.clone(), &yes_vote, &[]) - .unwrap_err(); - assert_eq!(ContractError::NotOpen {}, err.downcast().unwrap()); + .unwrap(); + // Verify + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Passed") + ] + ); // query individual votes + // initial (with 0 weight) + let voter = BANDWIDTH_CONTRACT.into(); + let vote: VoteResponse = app + .wrap() + .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) + .unwrap(); + assert_eq!( + vote.vote.unwrap(), + VoteInfo { + proposal_id, + voter: BANDWIDTH_CONTRACT.into(), + vote: Vote::Yes, + weight: 0 + } + ); + // nay sayer let voter = VOTER2.into(); let vote: VoteResponse = app @@ -1090,7 +1246,7 @@ mod tests { ); // non-voter - let voter = VOTER5.into(); + let voter = SOMEBODY.into(); let vote: VoteResponse = app .wrap() .query_wasm_smart(&flex_addr, &QueryMsg::Vote { proposal_id, voter }) @@ -1099,7 +1255,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1115,7 +1278,7 @@ mod tests { // Powerful voter opposes it, so it rejects let res = app - .execute_contract(Addr::unchecked(VOTER4), flex_addr, &no_vote, &[]) + .execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &no_vote, &[]) .unwrap(); assert_eq!( @@ -1127,6 +1290,25 @@ mod tests { ("status", "Rejected"), ], ); + + // Rejected proposals can still be voted (while they are not expired) + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + let res = app + .execute_contract(Addr::unchecked(VOTER5), flex_addr, &yes_vote, &[]) + .unwrap(); + + assert_eq!( + res.custom_attrs(1), + [ + ("action", "vote"), + ("sender", VOTER5), + ("proposal_id", proposal_id.to_string().as_str()), + ("status", "Rejected"), + ], + ); } #[test] @@ -1139,7 +1321,15 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // ensure we have cash to cover the proposal let contract_bal = app.wrap().query_balance(&flex_addr, "BTC").unwrap(); @@ -1147,7 +1337,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1227,6 +1424,142 @@ mod tests { ); } + #[test] + fn execute_with_executor_member() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(nym_multisig_contract_common::state::Executor::Member), // set executor as Member of voting group + None, + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER2)), // member of voting group is allowed to execute + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + + #[test] + fn execute_with_executor_only() { + let init_funds = coins(10, "BTC"); + let mut app = mock_app(&init_funds); + + let threshold = Threshold::ThresholdQuorum { + threshold: Decimal::percent(51), + quorum: Decimal::percent(1), + }; + let voting_period = Duration::Time(2000000); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + Some(nym_multisig_contract_common::state::Executor::Only( + Addr::unchecked(VOTER3), + )), // only VOTER3 can execute proposal + None, + ); + + // create proposal with 0 vote power + let proposal = pay_somebody_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + + // Vote it, so it passes + let vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &vote, &[]) + .unwrap(); + + let execution = ExecuteMsg::Execute { proposal_id }; + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked("anyone")), // anyone is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + let err = app + .execute_contract( + Addr::unchecked(Addr::unchecked(VOTER1)), // VOTER1 is not allowed to execute + flex_addr.clone(), + &execution, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err.downcast().unwrap()); + + app.execute_contract( + Addr::unchecked(Addr::unchecked(VOTER3)), // VOTER3 is allowed to execute + flex_addr, + &execution, + &[], + ) + .unwrap(); + } + #[test] fn proposal_pass_on_expiration() { let init_funds = coins(10, "BTC"); @@ -1243,6 +1576,8 @@ mod tests { Duration::Time(voting_period), init_funds, true, + None, + None, ); // ensure we have cash to cover the proposal @@ -1251,7 +1586,14 @@ mod tests { // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1287,6 +1629,17 @@ mod tests { .unwrap(); assert_eq!(prop.status, Status::Passed); + // Closing should NOT be possible + let err = app + .execute_contract( + Addr::unchecked(SOMEBODY), + flex_addr.clone(), + &ExecuteMsg::Close { proposal_id }, + &[], + ) + .unwrap_err(); + assert_eq!(ContractError::WrongCloseStatus {}, err.downcast().unwrap()); + // Execution should now be possible. let res = app .execute_contract( @@ -1316,11 +1669,26 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Height(2000000); - let (flex_addr, _) = setup_test_case(&mut app, threshold, voting_period, init_funds, true); + let (flex_addr, _) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + true, + None, + None, + ); // create proposal with 0 vote power let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, OWNER); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); @@ -1365,14 +1733,34 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER1 starts a proposal to send some tokens (1/4 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App, proposal_id: u64| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1430,9 +1818,22 @@ mod tests { // make a second proposal let proposal2 = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal2, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal2, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // VOTER2 can pass this alone with the updated vote (newer height ignores snapshot) let yes_vote = ExecuteMsg::Vote { @@ -1500,18 +1901,44 @@ mod tests { msgs: vec![update_msg], latest: None, }; - let res = propose_and_vote(&mut app, flex_addr.clone(), update_proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &update_proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let update_proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: update_proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // next block... app.update_block(|b| b.height += 1); // VOTER1 starts a proposal to send some tokens let cash_proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), cash_proposal, VOTER1); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &cash_proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let cash_proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: cash_proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER1), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); assert_ne!(cash_proposal_id, update_proposal_id); // query proposal state @@ -1593,14 +2020,34 @@ mod tests { quorum: Decimal::percent(1), }; let voting_period = Duration::Time(20000); - let (flex_addr, group_addr) = - setup_test_case(&mut app, threshold, voting_period, init_funds, false); + let (flex_addr, group_addr) = setup_test_case( + &mut app, + threshold, + voting_period, + init_funds, + false, + None, + None, + ); // VOTER3 starts a proposal to send some tokens (3/12 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER3); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER3), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1640,9 +2087,22 @@ mod tests { // new proposal can be passed single-handedly by newbie let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, newbie); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id2: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id: proposal_id2, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(newbie), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); // check proposal2 status let query_prop = QueryMsg::Proposal { @@ -1673,13 +2133,28 @@ mod tests { voting_period, init_funds, false, + None, + None, ); // VOTER3 starts a proposal to send some tokens (3 votes) let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER3); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER3), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1741,13 +2216,28 @@ mod tests { voting_period, init_funds, false, + None, + None, ); // create proposal let proposal = pay_somebody_proposal(); - let res = propose_and_vote(&mut app, flex_addr.clone(), proposal, VOTER5); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); // Get the proposal id from the logs let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER5), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); let prop_status = |app: &App| -> Status { let query_prop = QueryMsg::Proposal { proposal_id }; let prop: ProposalResponse = app @@ -1778,4 +2268,490 @@ mod tests { .unwrap(); assert_eq!(prop_status(&app), Status::Passed); } + + #[test] + fn test_instantiate_with_invalid_deposit() { + let mut app = App::default(); + + let flex_id = app.store_code(contract_flex()); + + let group_addr = instantiate_group( + &mut app, + vec![Member { + addr: OWNER.to_string(), + weight: 10, + }], + ); + + // Instantiate with an invalid cw20 token. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::new(1), + refund_failed_proposals: true, + denom: UncheckedDenom::Cw20(group_addr.to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::InvalidCw20 {})); + + // Instantiate with a zero amount. + let instantiate = InstantiateMsg { + group_addr: group_addr.to_string(), + coconut_bandwidth_contract_address: BANDWIDTH_CONTRACT.to_string(), + coconut_dkg_contract_address: DKG_CONTRACT.to_string(), + threshold: Threshold::AbsoluteCount { weight: 10 }, + max_voting_period: Duration::Time(10), + executor: None, + proposal_deposit: Some(UncheckedDepositInfo { + amount: Uint128::zero(), + refund_failed_proposals: true, + denom: UncheckedDenom::Native("native".to_string()), + }), + }; + + let err: ContractError = app + .instantiate_contract( + flex_id, + Addr::unchecked(OWNER), + &instantiate, + &[], + "Bad cw20", + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!(err, ContractError::Deposit(DepositError::ZeroDeposit {})) + } + + #[test] + fn test_cw20_proposal_deposit() { + let mut app = App::default(); + + let cw20_id = app.store_code(contract_cw20()); + + let cw20_addr = app + .instantiate_contract( + cw20_id, + Addr::unchecked(OWNER), + &cw20_base::msg::InstantiateMsg { + name: "Token".to_string(), + symbol: "TOKEN".to_string(), + decimals: 6, + initial_balances: vec![ + Cw20Coin { + address: VOTER4.to_string(), + amount: Uint128::new(10), + }, + Cw20Coin { + address: BANDWIDTH_CONTRACT.to_string(), + amount: Uint128::new(10), + }, + Cw20Coin { + address: OWNER.to_string(), + amount: Uint128::new(10), + }, + ], + mint: None, + marketing: None, + }, + &[], + "Token", + None, + ) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Cw20(cw20_addr.to_string()), + refund_failed_proposals: true, + }), + ); + + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that will pass. + let proposal = text_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); + + // Make sure the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: BANDWIDTH_CONTRACT.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::zero()); + + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + cw20_addr.clone(), + &cw20::Cw20ExecuteMsg::IncreaseAllowance { + spender: flex_addr.to_string(), + amount: Uint128::new(10), + expires: None, + }, + &[], + ) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[], + ) + .unwrap(); + + // Check that the deposit was transfered. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &cw20::Cw20QueryMsg::Balance { + address: flex_addr.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance: cw20::BalanceResponse = app + .wrap() + .query_wasm_smart( + cw20_addr, + &cw20::Cw20QueryMsg::Balance { + address: VOTER4.to_string(), + }, + ) + .unwrap(); + assert_eq!(balance.balance, Uint128::new(10)); + } + + #[test] + fn proposal_deposit_no_failed_refunds() { + let mut app = App::default(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: false, + }), + ); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: BANDWIDTH_CONTRACT.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + // Check that the deposit was transfered. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 1, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Check that the deposit wasn't returned. + let balance = app + .wrap() + .query_balance(OWNER, "TOKEN".to_string()) + .unwrap(); + assert_eq!(balance.amount, Uint128::zero()); + } + + #[test] + fn test_native_proposal_deposit() { + let mut app = App::default(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: VOTER4.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + app.sudo(SudoMsg::Bank(BankSudo::Mint { + to_address: BANDWIDTH_CONTRACT.to_string(), + amount: vec![Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + })) + .unwrap(); + + let (flex_addr, _) = setup_test_case( + &mut app, + Threshold::AbsoluteCount { weight: 10 }, + Duration::Height(10), + vec![], + true, + None, + Some(UncheckedDepositInfo { + amount: Uint128::new(10), + denom: UncheckedDenom::Native("TOKEN".to_string()), + refund_failed_proposals: true, + }), + ); + + // Make a proposal that will pass. + let proposal = text_proposal(); + let res = app + .execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + // Get the proposal id from the logs + let proposal_id: u64 = res.custom_attrs(1)[2].value.parse().unwrap(); + let yes_vote = ExecuteMsg::Vote { + proposal_id, + vote: Vote::Yes, + }; + app.execute_contract(Addr::unchecked(VOTER4), flex_addr.clone(), &yes_vote, &[]) + .unwrap(); + + // Make sure the deposit was transfered. + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Execute { proposal_id: 1 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned. + let balance = app.wrap().query_balance(VOTER4, "TOKEN").unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Make a proposal that fails. + let proposal = text_proposal(); + app.execute_contract( + Addr::unchecked(BANDWIDTH_CONTRACT), + flex_addr.clone(), + &proposal, + &[Coin { + amount: Uint128::new(10), + denom: "TOKEN".to_string(), + }], + ) + .unwrap(); + + let balance = app + .wrap() + .query_balance(flex_addr.clone(), "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + + // Fail the proposal. + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr.clone(), + &ExecuteMsg::Vote { + proposal_id: 2, + vote: Vote::No, + }, + &[], + ) + .unwrap(); + + // Expire the proposal. + app.update_block(|b| b.height += 10); + + app.execute_contract( + Addr::unchecked(VOTER4), + flex_addr, + &ExecuteMsg::Close { proposal_id: 2 }, + &[], + ) + .unwrap(); + + // Make sure the deposit was returned despite the proposal failing. + let balance = app + .wrap() + .query_balance(BANDWIDTH_CONTRACT, "TOKEN") + .unwrap(); + assert_eq!(balance.amount, Uint128::new(10)); + } } diff --git a/contracts/multisig/cw3-flex-multisig/src/lib.rs b/contracts/multisig/cw3-flex-multisig/src/lib.rs index 3407c199dd..bc3020f956 100644 --- a/contracts/multisig/cw3-flex-multisig/src/lib.rs +++ b/contracts/multisig/cw3-flex-multisig/src/lib.rs @@ -1,2 +1,25 @@ +/*! +This builds on [`cw3_fixed_multisig`] with a more +powerful implementation of the [cw3 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). +It is a multisig contract that is backed by a +[cw4 (group)](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md) contract, which independently +maintains the voter set. + +This provides 2 main advantages: + +* You can create two different multisigs with different voting thresholds + backed by the same group. Thus, you can have a 50% vote, and a 67% vote + that always use the same voter set, but can take other actions. +* TODO: It allows dynamic multisig groups. + + +In addition to the dynamic voting set, the main difference with the native +Cosmos SDK multisig, is that it aggregates the signatures on chain, with +visible proposals (like `x/gov` in the Cosmos SDK), rather than requiring +signers to share signatures off chain. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw3-flex-multisig/README.md). + */ + pub mod contract; -pub mod state; diff --git a/contracts/multisig/cw3-flex-multisig/src/state.rs b/contracts/multisig/cw3-flex-multisig/src/state.rs deleted file mode 100644 index 0826f1014e..0000000000 --- a/contracts/multisig/cw3-flex-multisig/src/state.rs +++ /dev/null @@ -1,20 +0,0 @@ -use cosmwasm_std::Addr; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cw4::Cw4Contract; -use cw_storage_plus::Item; -use cw_utils::{Duration, Threshold}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct Config { - pub threshold: Threshold, - pub max_voting_period: Duration, - // Total weight and voters are queried from this contract - pub group_addr: Cw4Contract, - pub coconut_bandwidth_addr: Addr, - pub coconut_dkg_addr: Addr, -} - -// unique items -pub const CONFIG: Item = Item::new("config"); diff --git a/contracts/multisig/cw4-group/.cargo/config b/contracts/multisig/cw4-group/.cargo/config index 7d1a066c82..4c5472df3b 100644 --- a/contracts/multisig/cw4-group/.cargo/config +++ b/contracts/multisig/cw4-group/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema" \ No newline at end of file diff --git a/contracts/multisig/cw4-group/Cargo.toml b/contracts/multisig/cw4-group/Cargo.toml index 4605ec5bcc..180ee66b9d 100644 --- a/contracts/multisig/cw4-group/Cargo.toml +++ b/contracts/multisig/cw4-group/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "cw4-group" -version = "0.13.4" +version = "1.0.0" authors = ["Ethan Frey "] -edition = "2018" +edition = "2021" description = "Simple cw4 implementation of group membership controlled by admin " license = "Apache-2.0" repository = "https://github.com/CosmWasm/cw-plus" @@ -20,6 +20,8 @@ exclude = [ crate-type = ["cdylib", "rlib"] [features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] @@ -31,10 +33,8 @@ cw2 = { workspace = true } cw4 = { workspace = true } cw-controllers = { workspace = true } cw-storage-plus = { workspace = true } +cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } schemars = "0.8.1" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" } - -[dev-dependencies] -cosmwasm-schema = { workspace = true } diff --git a/contracts/multisig/cw4-group/src/contract.rs b/contracts/multisig/cw4-group/src/contract.rs index c141210507..a6069f3b23 100644 --- a/contracts/multisig/cw4-group/src/contract.rs +++ b/contracts/multisig/cw4-group/src/contract.rs @@ -2,7 +2,7 @@ use cosmwasm_std::entry_point; use cosmwasm_std::{ attr, to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, - SubMsg, + SubMsg, Uint64, }; use cw2::set_contract_version; use cw4::{ @@ -13,6 +13,7 @@ use cw_storage_plus::Bound; use cw_utils::maybe_addr; use crate::error::ContractError; +use crate::helpers::validate_unique_members; use crate::state::{ADMIN, HOOKS, MEMBERS, TOTAL}; use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -39,21 +40,25 @@ pub fn instantiate( pub fn create( mut deps: DepsMut, admin: Option, - members: Vec, + mut members: Vec, height: u64, ) -> Result<(), ContractError> { + validate_unique_members(&mut members)?; + let members = members; // let go of mutability + let admin_addr = admin .map(|admin| deps.api.addr_validate(&admin)) .transpose()?; ADMIN.set(deps.branch(), admin_addr)?; - let mut total = 0u64; + let mut total = Uint64::zero(); for member in members.into_iter() { - total += member.weight; + let member_weight = Uint64::from(member.weight); + total = total.checked_add(member_weight)?; let member_addr = deps.api.addr_validate(&member.addr)?; - MEMBERS.save(deps.storage, &member_addr, &member.weight, height)?; + MEMBERS.save(deps.storage, &member_addr, &member_weight.u64(), height)?; } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(()) } @@ -115,20 +120,23 @@ pub fn update_members( deps: DepsMut, height: u64, sender: Addr, - to_add: Vec, + mut to_add: Vec, to_remove: Vec, ) -> Result { + validate_unique_members(&mut to_add)?; + let to_add = to_add; // let go of mutability + ADMIN.assert_admin(deps.as_ref(), &sender)?; - let mut total = TOTAL.load(deps.storage)?; + let mut total = Uint64::from(TOTAL.load(deps.storage)?); let mut diffs: Vec = vec![]; // add all new members and update total for add in to_add.into_iter() { let add_addr = deps.api.addr_validate(&add.addr)?; MEMBERS.update(deps.storage, &add_addr, height, |old| -> StdResult<_> { - total -= old.unwrap_or_default(); - total += add.weight; + total = total.checked_sub(Uint64::from(old.unwrap_or_default()))?; + total = total.checked_add(Uint64::from(add.weight))?; diffs.push(MemberDiff::new(add.addr, old, Some(add.weight))); Ok(add.weight) })?; @@ -140,12 +148,12 @@ pub fn update_members( // Only process this if they were actually in the list before if let Some(weight) = old { diffs.push(MemberDiff::new(remove, Some(weight), None)); - total -= weight; + total = total.checked_sub(Uint64::from(weight))?; MEMBERS.remove(deps.storage, &remove_addr, height)?; } } - TOTAL.save(deps.storage, &total)?; + TOTAL.save(deps.storage, &total.u64(), height)?; Ok(MemberChangedHookMsg { diffs }) } @@ -157,20 +165,26 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { at_height: height, } => to_binary(&query_member(deps, addr, height)?), QueryMsg::ListMembers { start_after, limit } => { - to_binary(&list_members(deps, start_after, limit)?) + to_binary(&query_list_members(deps, start_after, limit)?) + } + QueryMsg::TotalWeight { at_height: height } => { + to_binary(&query_total_weight(deps, height)?) } - QueryMsg::TotalWeight {} => to_binary(&query_total_weight(deps)?), QueryMsg::Admin {} => to_binary(&ADMIN.query_admin(deps)?), QueryMsg::Hooks {} => to_binary(&HOOKS.query_hooks(deps)?), } } -fn query_total_weight(deps: Deps) -> StdResult { - let weight = TOTAL.load(deps.storage)?; +pub fn query_total_weight(deps: Deps, height: Option) -> StdResult { + let weight = match height { + Some(h) => TOTAL.may_load_at_height(deps.storage, h), + None => TOTAL.may_load(deps.storage), + }? + .unwrap_or_default(); Ok(TotalWeightResponse { weight }) } -fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { +pub fn query_member(deps: Deps, addr: String, height: Option) -> StdResult { let addr = deps.api.addr_validate(&addr)?; let weight = match height { Some(h) => MEMBERS.may_load_at_height(deps.storage, &addr, h), @@ -183,7 +197,7 @@ fn query_member(deps: Deps, addr: String, height: Option) -> StdResult, limit: Option, @@ -205,352 +219,3 @@ fn list_members( Ok(MemberListResponse { members }) } - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{from_slice, Api, OwnedDeps, Querier, Storage}; - use cw4::{member_key, TOTAL_KEY}; - use cw_controllers::{AdminError, HookError}; - - const INIT_ADMIN: &str = "juan"; - const USER1: &str = "somebody"; - const USER2: &str = "else"; - const USER3: &str = "funny"; - - fn do_instantiate(deps: DepsMut) { - let msg = InstantiateMsg { - admin: Some(INIT_ADMIN.into()), - members: vec![ - Member { - addr: USER1.into(), - weight: 11, - }, - Member { - addr: USER2.into(), - weight: 6, - }, - ], - }; - let info = mock_info("creator", &[]); - instantiate(deps, mock_env(), info, msg).unwrap(); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // it worked, let's query the state - let res = ADMIN.query_admin(deps.as_ref()).unwrap(); - assert_eq!(Some(INIT_ADMIN.into()), res.admin); - - let res = query_total_weight(deps.as_ref()).unwrap(); - assert_eq!(17, res.weight); - } - - #[test] - fn try_member_queries() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); - assert_eq!(member1.weight, Some(11)); - - let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); - assert_eq!(member2.weight, Some(6)); - - let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); - assert_eq!(member3.weight, None); - - let members = list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(members.members.len(), 2); - // TODO: assert the set is proper - } - - fn assert_users( - deps: &OwnedDeps, - user1_weight: Option, - user2_weight: Option, - user3_weight: Option, - height: Option, - ) { - let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); - assert_eq!(member1.weight, user1_weight); - - let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); - assert_eq!(member2.weight, user2_weight); - - let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); - assert_eq!(member3.weight, user3_weight); - - // this is only valid if we are not doing a historical query - if height.is_none() { - // compute expected metrics - let weights = [user1_weight, user2_weight, user3_weight]; - let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); - let count = weights.iter().filter(|x| x.is_some()).count(); - - // TODO: more detailed compare? - let members = list_members(deps.as_ref(), None, None).unwrap(); - assert_eq!(count, members.members.len()); - - let total = query_total_weight(deps.as_ref()).unwrap(); - assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 - } - } - - #[test] - fn add_new_remove_old_member() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER3.into(), - weight: 15, - }]; - let remove = vec![USER1.into()]; - - // non-admin cannot update - let height = mock_env().block.height; - let err = update_members( - deps.as_mut(), - height + 5, - Addr::unchecked(USER1), - add.clone(), - remove.clone(), - ) - .unwrap_err(); - assert_eq!(err, AdminError::NotAdmin {}.into()); - - // Test the values from instantiate - assert_users(&deps, Some(11), Some(6), None, None); - // Note all values were set at height, the beginning of that block was all None - assert_users(&deps, None, None, None, Some(height)); - // This will get us the values at the start of the block after instantiate (expected initial values) - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - - // admin updates properly - update_members( - deps.as_mut(), - height + 10, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - - // updated properly - assert_users(&deps, None, Some(6), Some(15), None); - - // snapshot still shows old value - assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); - } - - #[test] - fn add_old_remove_new_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // add a new one and remove existing one - let add = vec![Member { - addr: USER1.into(), - weight: 4, - }]; - let remove = vec![USER3.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, Some(4), Some(6), None, None); - } - - #[test] - fn add_and_remove_same_member() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER1.into()]; - - // admin updates properly - let height = mock_env().block.height; - update_members( - deps.as_mut(), - height, - Addr::unchecked(INIT_ADMIN), - add, - remove, - ) - .unwrap(); - assert_users(&deps, None, Some(6), Some(5), None); - } - - #[test] - fn add_remove_hooks() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - - // non-admin cannot add hook - let user_info = mock_info(USER1, &[]); - let err = execute( - deps.as_mut(), - mock_env(), - user_info.clone(), - add_msg.clone(), - ) - .unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // admin can add it, and it appears in the query - let admin_info = mock_info(INIT_ADMIN, &[]); - let _ = execute( - deps.as_mut(), - mock_env(), - admin_info.clone(), - add_msg.clone(), - ) - .unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone()]); - - // cannot remove a non-registered contract - let remove_msg = ExecuteMsg::RemoveHook { - addr: contract2.clone(), - }; - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); - assert_eq!(err, HookError::HookNotRegistered {}.into()); - - // add second contract - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); - - // cannot re-add an existing contract - let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); - assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); - - // non-admin cannot remove - let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; - let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); - assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); - - // remove the original - let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert_eq!(hooks.hooks, vec![contract2]); - } - - #[test] - fn hooks_fire() { - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); - assert!(hooks.hooks.is_empty()); - - let contract1 = String::from("hook1"); - let contract2 = String::from("hook2"); - - // register 2 hooks - let admin_info = mock_info(INIT_ADMIN, &[]); - let add_msg = ExecuteMsg::AddHook { - addr: contract1.clone(), - }; - let add_msg2 = ExecuteMsg::AddHook { - addr: contract2.clone(), - }; - for msg in [add_msg, add_msg2] { - let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); - } - - // make some changes - add 3, remove 2, and update 1 - // USER1 is updated and remove in the same call, we should remove this an add member3 - let add = vec![ - Member { - addr: USER1.into(), - weight: 20, - }, - Member { - addr: USER3.into(), - weight: 5, - }, - ]; - let remove = vec![USER2.into()]; - let msg = ExecuteMsg::UpdateMembers { remove, add }; - - // admin updates properly - assert_users(&deps, Some(11), Some(6), None, None); - let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); - assert_users(&deps, Some(20), None, Some(5), None); - - // ensure 2 messages for the 2 hooks - assert_eq!(res.messages.len(), 2); - // same order as in the message (adds first, then remove) - let diffs = vec![ - MemberDiff::new(USER1, Some(11), Some(20)), - MemberDiff::new(USER3, None, Some(5)), - MemberDiff::new(USER2, Some(6), None), - ]; - let hook_msg = MemberChangedHookMsg { diffs }; - let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); - let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); - assert_eq!(res.messages, vec![msg1, msg2]); - } - - #[test] - fn raw_queries_work() { - // add will over-write and remove have no effect - let mut deps = mock_dependencies(); - do_instantiate(deps.as_mut()); - - // get total from raw key - let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); - let total: u64 = from_slice(&total_raw).unwrap(); - assert_eq!(17, total); - - // get member votes from raw key - let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); - let member2: u64 = from_slice(&member2_raw).unwrap(); - assert_eq!(6, member2); - - // and execute misses - let member3_raw = deps.storage.get(&member_key(USER3)); - assert_eq!(None, member3_raw); - } -} diff --git a/contracts/multisig/cw4-group/src/error.rs b/contracts/multisig/cw4-group/src/error.rs index 8c88fb2255..bd5acb30fb 100644 --- a/contracts/multisig/cw4-group/src/error.rs +++ b/contracts/multisig/cw4-group/src/error.rs @@ -1,19 +1,25 @@ -use cosmwasm_std::StdError; +use cosmwasm_std::{OverflowError, StdError}; use thiserror::Error; use cw_controllers::{AdminError, HookError}; #[derive(Error, Debug, PartialEq)] pub enum ContractError { - #[error(transparent)] + #[error("{0}")] Std(#[from] StdError), - #[error(transparent)] + #[error("{0}")] Hook(#[from] HookError), - #[error(transparent)] + #[error("{0}")] Admin(#[from] AdminError), + #[error("{0}")] + Overflow(#[from] OverflowError), + #[error("Unauthorized")] Unauthorized {}, + + #[error("Message contained duplicate member: {member}")] + DuplicateMember { member: String }, } diff --git a/contracts/multisig/cw4-group/src/helpers.rs b/contracts/multisig/cw4-group/src/helpers.rs index eae8a2434e..c6b5d0187c 100644 --- a/contracts/multisig/cw4-group/src/helpers.rs +++ b/contracts/multisig/cw4-group/src/helpers.rs @@ -1,17 +1,17 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; use std::ops::Deref; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use cw4::{Cw4Contract, Member}; +use crate::ContractError; use nym_group_contract_common::msg::ExecuteMsg; /// Cw4GroupContract is a wrapper around Cw4Contract that provides a lot of helpers /// for working with cw4-group contracts. /// /// It extends Cw4Contract to add the extra calls from cw4-group. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] +#[cw_serde] pub struct Cw4GroupContract(pub Cw4Contract); impl Deref for Cw4GroupContract { @@ -41,3 +41,17 @@ impl Cw4GroupContract { self.encode_msg(msg) } } + +/// Sorts the slice and verifies all member addresses are unique. +pub fn validate_unique_members(members: &mut [Member]) -> Result<(), ContractError> { + members.sort_by(|a, b| a.addr.cmp(&b.addr)); + for (a, b) in members.iter().zip(members.iter().skip(1)) { + if a.addr == b.addr { + return Err(ContractError::DuplicateMember { + member: a.addr.clone(), + }); + } + } + + Ok(()) +} diff --git a/contracts/multisig/cw4-group/src/lib.rs b/contracts/multisig/cw4-group/src/lib.rs index 3870baf04b..06fd08f822 100644 --- a/contracts/multisig/cw4-group/src/lib.rs +++ b/contracts/multisig/cw4-group/src/lib.rs @@ -1,6 +1,25 @@ +/*! +This is a basic implementation of the [cw4 spec](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw4/README.md). +It fulfills all elements of the spec, including the raw query lookups, +and it designed to be used as a backing storage for +[cw3 compliant contracts](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw3/README.md). + +It stores a set of members along with an admin, and allows the admin to +update the state. Raw queries (intended for cross-contract queries) +can check a given member address and the total weight. Smart queries (designed +for client API) can do the same, and also query the admin address as well as +paginate over all members. + +For more information on this contract, please check out the +[README](https://github.com/CosmWasm/cw-plus/blob/main/contracts/cw4-group/README.md). + */ + pub mod contract; pub mod error; pub mod helpers; pub mod state; pub use crate::error::ContractError; + +#[cfg(test)] +mod tests; diff --git a/contracts/multisig/cw4-group/src/state.rs b/contracts/multisig/cw4-group/src/state.rs index 1b5003c985..10497fa99d 100644 --- a/contracts/multisig/cw4-group/src/state.rs +++ b/contracts/multisig/cw4-group/src/state.rs @@ -1,16 +1,24 @@ use cosmwasm_std::Addr; -use cw4::TOTAL_KEY; +use cw4::{ + MEMBERS_CHANGELOG, MEMBERS_CHECKPOINTS, MEMBERS_KEY, TOTAL_KEY, TOTAL_KEY_CHANGELOG, + TOTAL_KEY_CHECKPOINTS, +}; use cw_controllers::{Admin, Hooks}; -use cw_storage_plus::{Item, SnapshotMap, Strategy}; +use cw_storage_plus::{SnapshotItem, SnapshotMap, Strategy}; pub const ADMIN: Admin = Admin::new("admin"); pub const HOOKS: Hooks = Hooks::new("cw4-hooks"); -pub const TOTAL: Item = Item::new(TOTAL_KEY); - -pub const MEMBERS: SnapshotMap<&Addr, u64> = SnapshotMap::new( - cw4::MEMBERS_KEY, - cw4::MEMBERS_CHECKPOINTS, - cw4::MEMBERS_CHANGELOG, +pub const TOTAL: SnapshotItem = SnapshotItem::new( + TOTAL_KEY, + TOTAL_KEY_CHECKPOINTS, + TOTAL_KEY_CHANGELOG, + Strategy::EveryBlock, +); + +pub const MEMBERS: SnapshotMap<&Addr, u64> = SnapshotMap::new( + MEMBERS_KEY, + MEMBERS_CHECKPOINTS, + MEMBERS_CHANGELOG, Strategy::EveryBlock, ); diff --git a/contracts/multisig/cw4-group/src/tests.rs b/contracts/multisig/cw4-group/src/tests.rs new file mode 100644 index 0000000000..11f39f7084 --- /dev/null +++ b/contracts/multisig/cw4-group/src/tests.rs @@ -0,0 +1,439 @@ +use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; +use cosmwasm_std::{from_slice, Addr, Api, DepsMut, OwnedDeps, Querier, Storage, SubMsg}; +use cw4::{member_key, Member, MemberChangedHookMsg, MemberDiff, TOTAL_KEY}; +use cw_controllers::{AdminError, HookError}; + +use crate::contract::{ + execute, instantiate, query_list_members, query_member, query_total_weight, update_members, +}; +use crate::state::{ADMIN, HOOKS}; +use crate::ContractError; +use nym_group_contract_common::msg::{ExecuteMsg, InstantiateMsg}; + +const INIT_ADMIN: &str = "juan"; +const USER1: &str = "somebody"; +const USER2: &str = "else"; +const USER3: &str = "funny"; + +fn set_up(deps: DepsMut) { + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ + Member { + addr: USER1.into(), + weight: 11, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + ], + }; + let info = mock_info("creator", &[]); + instantiate(deps, mock_env(), info, msg).unwrap(); +} + +#[test] +fn proper_instantiation() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // it worked, let's query the state + let res = ADMIN.query_admin(deps.as_ref()).unwrap(); + assert_eq!(Some(INIT_ADMIN.into()), res.admin); + + let res = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, res.weight); +} + +#[test] +fn try_member_queries() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let member1 = query_member(deps.as_ref(), USER1.into(), None).unwrap(); + assert_eq!(member1.weight, Some(11)); + + let member2 = query_member(deps.as_ref(), USER2.into(), None).unwrap(); + assert_eq!(member2.weight, Some(6)); + + let member3 = query_member(deps.as_ref(), USER3.into(), None).unwrap(); + assert_eq!(member3.weight, None); + + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(members.members.len(), 2); + // TODO: assert the set is proper +} + +#[test] +fn duplicate_members_instantiation() { + let mut deps = mock_dependencies(); + + let msg = InstantiateMsg { + admin: Some(INIT_ADMIN.into()), + members: vec![ + Member { + addr: USER1.into(), + weight: 5, + }, + Member { + addr: USER2.into(), + weight: 6, + }, + Member { + addr: USER1.into(), + weight: 6, + }, + ], + }; + let info = mock_info("creator", &[]); + let err = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::DuplicateMember { + member: USER1.to_string() + } + ); +} + +#[test] +fn duplicate_members_execution() { + let mut deps = mock_dependencies(); + + set_up(deps.as_mut()); + + let add = vec![ + Member { + addr: USER3.into(), + weight: 15, + }, + Member { + addr: USER3.into(), + weight: 11, + }, + ]; + + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(INIT_ADMIN), + add, + vec![], + ) + .unwrap_err(); + + assert_eq!( + err, + ContractError::DuplicateMember { + member: USER3.to_string() + } + ); +} + +fn assert_users( + deps: &OwnedDeps, + user1_weight: Option, + user2_weight: Option, + user3_weight: Option, + height: Option, +) { + let member1 = query_member(deps.as_ref(), USER1.into(), height).unwrap(); + assert_eq!(member1.weight, user1_weight); + + let member2 = query_member(deps.as_ref(), USER2.into(), height).unwrap(); + assert_eq!(member2.weight, user2_weight); + + let member3 = query_member(deps.as_ref(), USER3.into(), height).unwrap(); + assert_eq!(member3.weight, user3_weight); + + // this is only valid if we are not doing a historical query + if height.is_none() { + // compute expected metrics + let weights = [user1_weight, user2_weight, user3_weight]; + let sum: u64 = weights.iter().map(|x| x.unwrap_or_default()).sum(); + let count = weights.iter().filter(|x| x.is_some()).count(); + + // TODO: more detailed compare? + let members = query_list_members(deps.as_ref(), None, None).unwrap(); + assert_eq!(count, members.members.len()); + + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(sum, total.weight); // 17 - 11 + 15 = 21 + } +} + +#[test] +fn add_new_remove_old_member() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER3.into(), + weight: 15, + }]; + let remove = vec![USER1.into()]; + + // non-admin cannot update + let height = mock_env().block.height; + let err = update_members( + deps.as_mut(), + height + 5, + Addr::unchecked(USER1), + add.clone(), + remove.clone(), + ) + .unwrap_err(); + assert_eq!(err, AdminError::NotAdmin {}.into()); + + // Test the values from instantiate + assert_users(&deps, Some(11), Some(6), None, None); + // Note all values were set at height, the beginning of that block was all None + assert_users(&deps, None, None, None, Some(height)); + // This will get us the values at the start of the block after instantiate (expected initial values) + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); + + // admin updates properly + update_members( + deps.as_mut(), + height + 10, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + + // updated properly + assert_users(&deps, None, Some(6), Some(15), None); + + // snapshot still shows old value + assert_users(&deps, Some(11), Some(6), None, Some(height + 1)); +} + +#[test] +fn add_old_remove_new_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // add a new one and remove existing one + let add = vec![Member { + addr: USER1.into(), + weight: 4, + }]; + let remove = vec![USER3.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, Some(4), Some(6), None, None); +} + +#[test] +fn add_and_remove_same_member() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER1.into()]; + + // admin updates properly + let height = mock_env().block.height; + update_members( + deps.as_mut(), + height, + Addr::unchecked(INIT_ADMIN), + add, + remove, + ) + .unwrap(); + assert_users(&deps, None, Some(6), Some(5), None); +} + +#[test] +fn add_remove_hooks() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + + // non-admin cannot add hook + let user_info = mock_info(USER1, &[]); + let err = execute( + deps.as_mut(), + mock_env(), + user_info.clone(), + add_msg.clone(), + ) + .unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // admin can add it, and it appears in the query + let admin_info = mock_info(INIT_ADMIN, &[]); + let _ = execute( + deps.as_mut(), + mock_env(), + admin_info.clone(), + add_msg.clone(), + ) + .unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone()]); + + // cannot remove a non-registered contract + let remove_msg = ExecuteMsg::RemoveHook { + addr: contract2.clone(), + }; + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), remove_msg).unwrap_err(); + assert_eq!(err, HookError::HookNotRegistered {}.into()); + + // add second contract + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg2).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract1.clone(), contract2.clone()]); + + // cannot re-add an existing contract + let err = execute(deps.as_mut(), mock_env(), admin_info.clone(), add_msg).unwrap_err(); + assert_eq!(err, HookError::HookAlreadyRegistered {}.into()); + + // non-admin cannot remove + let remove_msg = ExecuteMsg::RemoveHook { addr: contract1 }; + let err = execute(deps.as_mut(), mock_env(), user_info, remove_msg.clone()).unwrap_err(); + assert_eq!(err, HookError::Admin(AdminError::NotAdmin {}).into()); + + // remove the original + let _ = execute(deps.as_mut(), mock_env(), admin_info, remove_msg).unwrap(); + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert_eq!(hooks.hooks, vec![contract2]); +} + +#[test] +fn hooks_fire() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let hooks = HOOKS.query_hooks(deps.as_ref()).unwrap(); + assert!(hooks.hooks.is_empty()); + + let contract1 = String::from("hook1"); + let contract2 = String::from("hook2"); + + // register 2 hooks + let admin_info = mock_info(INIT_ADMIN, &[]); + let add_msg = ExecuteMsg::AddHook { + addr: contract1.clone(), + }; + let add_msg2 = ExecuteMsg::AddHook { + addr: contract2.clone(), + }; + for msg in [add_msg, add_msg2] { + let _ = execute(deps.as_mut(), mock_env(), admin_info.clone(), msg).unwrap(); + } + + // make some changes - add 3, remove 2, and update 1 + // USER1 is updated and remove in the same call, we should remove this an add member3 + let add = vec![ + Member { + addr: USER1.into(), + weight: 20, + }, + Member { + addr: USER3.into(), + weight: 5, + }, + ]; + let remove = vec![USER2.into()]; + let msg = ExecuteMsg::UpdateMembers { remove, add }; + + // admin updates properly + assert_users(&deps, Some(11), Some(6), None, None); + let res = execute(deps.as_mut(), mock_env(), admin_info, msg).unwrap(); + assert_users(&deps, Some(20), None, Some(5), None); + + // ensure 2 messages for the 2 hooks + assert_eq!(res.messages.len(), 2); + // same order as in the message (adds first, then remove) + // order of added users is not guaranteed to be preserved + let diffs = vec![ + MemberDiff::new(USER3, None, Some(5)), + MemberDiff::new(USER1, Some(11), Some(20)), + MemberDiff::new(USER2, Some(6), None), + ]; + let hook_msg = MemberChangedHookMsg { diffs }; + let msg1 = SubMsg::new(hook_msg.clone().into_cosmos_msg(contract1).unwrap()); + let msg2 = SubMsg::new(hook_msg.into_cosmos_msg(contract2).unwrap()); + dbg!(&res.messages); + dbg!(&msg1); + dbg!(&msg2); + assert_eq!(res.messages, vec![msg1, msg2]); +} + +#[test] +fn raw_queries_work() { + // add will over-write and remove have no effect + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + // get total from raw key + let total_raw = deps.storage.get(TOTAL_KEY.as_bytes()).unwrap(); + let total: u64 = from_slice(&total_raw).unwrap(); + assert_eq!(17, total); + + // get member votes from raw key + let member2_raw = deps.storage.get(&member_key(USER2)).unwrap(); + let member2: u64 = from_slice(&member2_raw).unwrap(); + assert_eq!(6, member2); + + // and execute misses + let member3_raw = deps.storage.get(&member_key(USER3)); + assert_eq!(None, member3_raw); +} + +#[test] +fn total_at_height() { + let mut deps = mock_dependencies(); + set_up(deps.as_mut()); + + let height = mock_env().block.height; + + // Test the values from instantiate + let total = query_total_weight(deps.as_ref(), None).unwrap(); + assert_eq!(17, total.weight); + // Note all values were set at height, the beginning of that block was all None + let total = query_total_weight(deps.as_ref(), Some(height)).unwrap(); + assert_eq!(0, total.weight); + // This will get us the values at the start of the block after instantiate (expected initial values) + let total = query_total_weight(deps.as_ref(), Some(height + 1)).unwrap(); + assert_eq!(17, total.weight); +} diff --git a/contracts/name-service/src/state/names.rs b/contracts/name-service/src/state/names.rs index 27af9f3407..3b2b02f82d 100644 --- a/contracts/name-service/src/state/names.rs +++ b/contracts/name-service/src/state/names.rs @@ -30,12 +30,12 @@ fn names<'a>() -> IndexedMap<'a, NameId, RegisteredName, NameIndex<'a>> { let indexes = NameIndex { name: UniqueIndex::new(|d| d.name.name.to_string(), NAMES_NAME_IDX_NAMESPACE), address: MultiIndex::new( - |d| d.name.address.to_string(), + |_pk, d| d.name.address.to_string(), NAMES_PK_NAMESPACE, NAMES_ADDRESS_IDX_NAMESPACE, ), owner: MultiIndex::new( - |d| d.owner.clone(), + |_pk, d| d.owner.clone(), NAMES_PK_NAMESPACE, NAMES_OWNER_IDX_NAMESPACE, ), diff --git a/contracts/service-provider-directory/src/state/services.rs b/contracts/service-provider-directory/src/state/services.rs index 54b9c27bcf..e5e68a21ff 100644 --- a/contracts/service-provider-directory/src/state/services.rs +++ b/contracts/service-provider-directory/src/state/services.rs @@ -26,12 +26,12 @@ impl<'a> IndexList for ServiceIndex<'a> { fn services<'a>() -> IndexedMap<'a, ServiceId, Service, ServiceIndex<'a>> { let indexes = ServiceIndex { nym_address: MultiIndex::new( - |d| d.service.nym_address.to_string(), + |_pk, d| d.service.nym_address.to_string(), SERVICES_PK_NAMESPACE, SERVICES_NYM_ADDRESS_IDX_NAMESPACE, ), announcer: MultiIndex::new( - |d| d.announcer.clone(), + |_pk, d| d.announcer.clone(), SERVICES_PK_NAMESPACE, SERVICES_ANNOUNCER_IDX_NAMESPACE, ), diff --git a/contracts/vesting/src/vesting/account/mod.rs b/contracts/vesting/src/vesting/account/mod.rs index 1e0aa25348..e59f27d1a2 100644 --- a/contracts/vesting/src/vesting/account/mod.rs +++ b/contracts/vesting/src/vesting/account/mod.rs @@ -25,7 +25,7 @@ fn generate_storage_key(storage: &mut dyn Storage) -> Result, diff --git a/explorer-api/src/mix_node/models.rs b/explorer-api/src/mix_node/models.rs index 462d41c3b5..94ae6558d0 100644 --- a/explorer-api/src/mix_node/models.rs +++ b/explorer-api/src/mix_node/models.rs @@ -45,7 +45,7 @@ pub(crate) struct PrettyDetailedMixNodeBond { pub blacklisted: bool, } -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)] pub struct SummedDelegations { pub owner: Addr, pub mix_id: MixId, diff --git a/integrations/bity/Cargo.toml b/integrations/bity/Cargo.toml index 8bab2b3e77..4ae51337c9 100644 --- a/integrations/bity/Cargo.toml +++ b/integrations/bity/Cargo.toml @@ -8,10 +8,10 @@ rust-version = "1.56" serde = { version = "1", features = ["derive"] } serde_json = "1" thiserror = "1.0" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { workspace = true, features = ["ecdsa", "sha256"] } eyre = "0.6.5" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } nym-cli-commands = { path = "../../common/commands" } nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index ed8dc1dce6..37aded5efa 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bs58 = "0.4.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = { workspace = true } cosmwasm-std = { workspace = true, default-features = false } getset = "0.1.1" schemars = { version = "0.8", features = ["preserve_order"] } diff --git a/nym-api/src/coconut/tests.rs b/nym-api/src/coconut/tests.rs index 7ebf4908a7..0648e9c8ca 100644 --- a/nym-api/src/coconut/tests.rs +++ b/nym-api/src/coconut/tests.rs @@ -443,6 +443,8 @@ impl super::client::Client for DummyClient { percentage: Decimal::from_ratio(2u32, 3u32), total_weight: 100, }, + proposer: Addr::unchecked(self.validator_address.as_ref()), + deposit: None, }; self.proposal_db .write() @@ -904,6 +906,8 @@ async fn verification_of_bandwidth_credential() { percentage: Decimal::from_ratio(2u32, 3u32), total_weight: 100, }, + proposer: Addr::unchecked("proposer"), + deposit: None, }; // Test the endpoint with a different blinded serial number in the description diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 0cb8b27caf..4b515a4f54 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -228,18 +228,18 @@ dependencies = [ [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac 0.11.0", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -326,7 +326,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -339,12 +338,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.5.0" @@ -707,9 +700,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" @@ -766,8 +759,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -776,8 +770,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -798,11 +793,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -811,26 +806,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.109", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -944,9 +966,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1064,10 +1086,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1078,9 +1101,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1089,22 +1112,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.17", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1112,11 +1139,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1124,11 +1152,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1196,11 +1240,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1354,9 +1410,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1410,16 +1466,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff 0.11.1", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group 0.11.0", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1550,6 +1608,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.5" @@ -2071,6 +2139,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "gtk" version = "0.15.5" @@ -2702,23 +2781,22 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -3524,6 +3602,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3540,7 +3620,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -3550,7 +3630,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -4200,11 +4282,11 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -4427,13 +4509,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -4833,12 +4914,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac 0.11.0", + "hmac 0.12.1", "zeroize", ] @@ -4881,6 +4962,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -5091,10 +5181,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -5190,6 +5281,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -5368,14 +5468,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -5398,11 +5496,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -5506,9 +5604,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -6150,9 +6248,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -6181,9 +6279,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -6195,9 +6293,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -6213,9 +6311,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index fa2722e281..14bc9eb0e6 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -122,9 +122,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" @@ -220,18 +220,18 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "bip32" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ "bs58", - "hmac", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", - "ripemd160", - "sha2 0.9.9", + "ripemd", + "sha2 0.10.6", "subtle 2.4.1", "zeroize", ] @@ -297,9 +297,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", "arrayvec", @@ -321,7 +321,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array 0.14.7", ] @@ -334,20 +333,14 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bls12_381" version = "0.6.0" source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278" dependencies = [ "digest 0.9.0", - "ff", - "group", + "ff 0.11.1", + "group 0.11.0", "pairing", "rand_core 0.6.4", "subtle 2.4.1", @@ -688,15 +681,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "constant_time_eq" -version = "0.2.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "convert_case" @@ -747,8 +740,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.12.3" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" dependencies = [ "prost", "prost-types", @@ -757,8 +751,9 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.7.1" -source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" dependencies = [ "bip32", "cosmos-sdk-proto", @@ -779,11 +774,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" +checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -792,26 +787,53 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.0.0" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773" dependencies = [ "syn 1.0.107", ] [[package]] -name = "cosmwasm-std" -version = "1.0.0" +name = "cosmwasm-schema" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", +] + +[[package]] +name = "cosmwasm-std" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb" dependencies = [ "base64 0.13.1", "cosmwasm-crypto", "cosmwasm-derive", + "derivative", "forward_ref", + "hex", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.1", + "sha2 0.10.6", "thiserror", "uint", ] @@ -857,14 +879,14 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] @@ -885,9 +907,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1011,10 +1033,11 @@ dependencies = [ [[package]] name = "cw-controllers" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa" +checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "cw-utils", @@ -1025,9 +1048,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa" dependencies = [ "cosmwasm-std", "schemars", @@ -1036,22 +1059,26 @@ dependencies = [ [[package]] name = "cw-utils" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw2", "schemars", + "semver 1.0.16", "serde", "thiserror", ] [[package]] name = "cw2" -version = "0.13.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1059,11 +1086,12 @@ dependencies = [ ] [[package]] -name = "cw3" -version = "0.13.4" +name = "cw20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-utils", "schemars", @@ -1071,11 +1099,27 @@ dependencies = [ ] [[package]] -name = "cw4" -version = "0.13.4" +name = "cw3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa" dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b" +dependencies = [ + "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", @@ -1119,11 +1163,23 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.107", ] [[package]] @@ -1271,9 +1327,9 @@ checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ "der", "elliptic-curve", @@ -1327,16 +1383,18 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", - "ff", + "digest 0.10.6", + "ff 0.12.1", "generic-array 0.14.7", - "group", + "group 0.12.1", + "pkcs8", "rand_core 0.6.4", "sec1", "subtle 2.4.1", @@ -1451,6 +1509,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.4" @@ -1921,7 +1989,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" dependencies = [ "byteorder", - "ff", + "ff 0.11.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", "rand_core 0.6.4", "subtle 2.4.1", ] @@ -2106,7 +2185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" dependencies = [ "digest 0.9.0", - "hmac", + "hmac 0.11.0", ] [[package]] @@ -2119,6 +2198,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -2496,23 +2584,22 @@ dependencies = [ [[package]] name = "k256" -version = "0.10.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -2700,9 +2787,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] @@ -2935,9 +3022,9 @@ dependencies = [ "bls12_381", "bs58", "digest 0.9.0", - "ff", + "ff 0.11.1", "getrandom 0.2.10", - "group", + "group 0.11.0", "itertools", "nym-dkg", "nym-pemstore", @@ -3027,8 +3114,8 @@ dependencies = [ "bitvec", "bls12_381", "bs58", - "ff", - "group", + "ff 0.11.1", + "group 0.11.0", "lazy_static", "nym-pemstore", "rand 0.8.5", @@ -3045,6 +3132,8 @@ dependencies = [ name = "nym-group-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", + "cw-controllers", "cw4", "schemars", "serde", @@ -3061,7 +3150,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.4.1", "serde_repr", "thiserror", "time", @@ -3072,7 +3161,9 @@ dependencies = [ name = "nym-multisig-contract-common" version = "0.1.0" dependencies = [ + "cosmwasm-schema", "cosmwasm-std", + "cw-storage-plus", "cw-utils", "cw3", "cw4", @@ -3499,7 +3590,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42" dependencies = [ - "group", + "group 0.11.0", ] [[package]] @@ -3575,11 +3666,11 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "crypto-mac 0.11.1", + "digest 0.10.6", ] [[package]] @@ -3802,13 +3893,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -4222,12 +4312,12 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -4270,6 +4360,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "ripemd160" version = "0.9.1" @@ -4423,10 +4522,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array 0.14.7", "pkcs8", @@ -4522,6 +4622,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-wasm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.9" @@ -4687,14 +4796,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug 0.3.0", ] [[package]] @@ -4717,11 +4824,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.9.0", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -4799,7 +4906,7 @@ dependencies = [ "curve25519-dalek", "digest 0.9.0", "hkdf", - "hmac", + "hmac 0.11.0", "lioness", "log", "rand 0.7.3", @@ -4816,9 +4923,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -5236,9 +5343,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" dependencies = [ "async-trait", "bytes", @@ -5267,9 +5374,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" dependencies = [ "flex-error", "serde", @@ -5281,9 +5388,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" dependencies = [ "bytes", "flex-error", @@ -5299,9 +5406,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" dependencies = [ "async-trait", "bytes", diff --git a/nym-wallet/Cargo.toml b/nym-wallet/Cargo.toml index 80e269fba7..de5e6faf93 100644 --- a/nym-wallet/Cargo.toml +++ b/nym-wallet/Cargo.toml @@ -5,4 +5,4 @@ members = [ "src-tauri", "nym-wallet-recovery-cli", "nym-wallet-types" -] +] \ No newline at end of file diff --git a/nym-wallet/nym-wallet-types/Cargo.toml b/nym-wallet/nym-wallet-types/Cargo.toml index 8d47e3d70d..99d0ef784b 100644 --- a/nym-wallet/nym-wallet-types/Cargo.toml +++ b/nym-wallet/nym-wallet-types/Cargo.toml @@ -12,7 +12,7 @@ strum = { version = "0.23", features = ["derive"] } ts-rs = "6.1.2" cosmwasm-std = "1.0.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = "=0.8.0" nym-config = { path = "../../common/config" } nym-network-defaults = { path = "../../common/network-defaults" } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 06757de614..2d65946c23 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -44,12 +44,12 @@ thiserror = "1.0" tokio = { version = "1.10", features = ["full"] } toml = "0.5.8" url = "2.2" -k256 = { version = "0.10", features = ["ecdsa", "sha256"] } +k256 = { version = "0.11", features = ["ecdsa", "sha256"] } base64 = "0.13" zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } cosmwasm-std = "1.0.0" -cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" } +cosmrs = "=0.8.0" nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ "nyxd-client", From 407d2800196f52af2f2992b7b136fbc27c690b99 Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 18 Jul 2023 11:23:15 +0200 Subject: [PATCH 19/59] fixes to GH action --- .github/workflows/nym-wallet-publish-macos.yml | 8 +++++--- .../workflows/nym-wallet-publish-ubuntu.yml | 18 ++++-------------- .../workflows/nym-wallet-publish-windows10.yml | 8 +++++--- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/.github/workflows/nym-wallet-publish-macos.yml b/.github/workflows/nym-wallet-publish-macos.yml index c21e99493d..5a87e38d1c 100644 --- a/.github/workflows/nym-wallet-publish-macos.yml +++ b/.github/workflows/nym-wallet-publish-macos.yml @@ -99,12 +99,14 @@ jobs: files: | nym-wallet/target/release/bundle/dmg/*.dmg nym-wallet/target/release/bundle/macos/*.app.tar.gz* + - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_$version_x64.dmg" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-wallet-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${version}_x64.dmg" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/dmg/nym-wallet_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 1dd673130c..027908e2f6 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -77,23 +77,13 @@ jobs: nym-wallet/target/release/bundle/appimage/*.AppImage nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz* - - name: Debug - run: | - ref=${{ github.ref_name }} - semver="${ref##nym-wallet-}" && semver="${semver##v}" - echo "$ref" - echo "${ref##nym-wallet-}" - echo "${semver}" - version="${semver}" - echo "nym-wallet_${version}_amd64.AppImage" - echo "${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" - - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_$version_amd64.AppImage" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-wallet-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-wallet-publish-windows10.yml b/.github/workflows/nym-wallet-publish-windows10.yml index 4ce6f38173..974de92435 100644 --- a/.github/workflows/nym-wallet-publish-windows10.yml +++ b/.github/workflows/nym-wallet-publish-windows10.yml @@ -96,12 +96,14 @@ jobs: files: | nym-wallet/target/release/bundle/msi/*.msi nym-wallet/target/release/bundle/msi/*.msi.zip* + - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-wallet_$version_x64_en-US.msi" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-wallet-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-wallet_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/msi/nym-wallet_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: From 63254ecffe91cbf581ecc27e323532675696343a Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 18 Jul 2023 13:43:30 +0200 Subject: [PATCH 20/59] update versions and changelogs for the release --- nym-wallet/CHANGELOG.md | 6 ++++++ nym-wallet/package.json | 4 ++-- nym-wallet/src-tauri/Cargo.toml | 2 +- nym-wallet/src-tauri/tauri.conf.json | 16 ++++++++++++---- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index 82a2dd9da7..f0d62aec2d 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [v1.2.6] (2023-07-18) + +- [wallet] bugfix: don't send funds for pledge decrease simulation ([#3676]) + +[#3676]: https://github.com/nymtech/nym/pull/3676 + ## [v1.2.5] (2023-07-04) - Wallet - add "Test my node" in the Node Settings and show its results ([#2314]) diff --git a/nym-wallet/package.json b/nym-wallet/package.json index f14d6dd227..e93b887fcf 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/nym-wallet-app", - "version": "1.2.5", + "version": "1.2.6", "main": "index.js", "license": "MIT", "scripts": { @@ -123,4 +123,4 @@ "webpack-favicons": "^1.3.8", "webpack-merge": "^5.8.0" } -} +} \ No newline at end of file diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 06757de614..a04ffabe0d 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.2.5" +version = "1.2.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 45ba45f846..2986866ccb 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.2.5" + "version": "1.2.6" }, "build": { "distDir": "../dist", @@ -14,7 +14,13 @@ "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"], + "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", @@ -39,7 +45,9 @@ }, "updater": { "active": true, - "endpoints": ["https://nymtech.net/.wellknown/wallet/updater.json"], + "endpoints": [ + "https://nymtech.net/.wellknown/wallet/updater.json" + ], "dialog": true, "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IENCNzQ2M0E5N0VFODE2NApSV1JrZ2U2WE9rYTNETTg1OTBKdE5uWUEra0hML2syOVUvQ2lxZmFZRzZ1T3NWbGM0eVRzUTVhVwo=" }, @@ -67,4 +75,4 @@ "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" } } -} +} \ No newline at end of file From c12b20f1d6648c0e52e422bb07d9f64b24c35a09 Mon Sep 17 00:00:00 2001 From: Fouad Date: Tue, 18 Jul 2023 14:09:40 +0100 Subject: [PATCH 21/59] Feature/sdk browser extension examples (#3673) * New TypeScript SDK example: Google Chrome Example of a simple manifest v3 extension to load a Nym client within a popup view. * Firefox Extension example for Nym TypeScript SDK * Fix typo * Add basic install script * fix up html files * remove unnecessary background page * bundle extensions with webpack * use icons from shared assets * ignore sdk index file * import sdk lib * create new build script for non-inline workers * import workers and build as separate files using webpack * update html titles * create react app node tester example * add readme file * update readme for FF extension * code formatting --------- Co-authored-by: Nadim Kobeissi Co-authored-by: Mark Sinclair --- .../examples/chrome-extension/README.md | 22 +++ .../examples/chrome-extension/manifest.json | 17 +++ .../examples/chrome-extension/package.json | 20 +++ .../examples/chrome-extension/popup.css | 8 ++ .../examples/chrome-extension/popup.html | 23 ++++ .../chrome-extension/src/dom-utils.js | 66 +++++++++ .../examples/chrome-extension/src/main.js | 53 ++++++++ .../chrome-extension/webpack.config.js | 25 ++++ .../examples/firefox-extension/.gitignore | 1 + .../examples/firefox-extension/README.md | 35 +++++ .../examples/firefox-extension/manifest.json | 23 ++++ .../examples/firefox-extension/package.json | 19 +++ .../examples/firefox-extension/popup.css | 8 ++ .../examples/firefox-extension/popup.html | 23 ++++ .../firefox-extension/src/background.js | 107 +++++++++++++++ .../firefox-extension/src/dom-utils.js | 74 ++++++++++ .../examples/firefox-extension/src/popup.js | 40 ++++++ .../firefox-extension/webpack.config.js | 38 ++++++ .../node-tester/parcel/src/index.html | 2 +- .../examples/node-tester/plain-html/.babelrc | 3 - .../node-tester/plain-html/jest.config.js | 5 - .../node-tester/plain-html/src/index.html | 2 +- .../examples/node-tester/react/README.md | 14 ++ .../examples/node-tester/react/index.html | 13 ++ .../examples/node-tester/react/package.json | 19 +++ .../examples/node-tester/react/src/App.tsx | 127 ++++++++++++++++++ .../react/src/components/ScoreIndicator.tsx | 61 +++++++++ .../react/src/components/TestStatusLabel.tsx | 34 +++++ .../react/src/hooks/useNodeTesterClient.ts | 71 ++++++++++ .../examples/node-tester/react/src/index.tsx | 14 ++ .../node-tester/react/src/layouts/index.tsx | 6 + .../node-tester/react/src/theme/theme.tsx | 28 ++++ .../node-tester/react/src/typesDefs.ts | 4 + .../examples/node-tester/react/tsconfig.json | 16 +++ sdk/typescript/packages/sdk/package.json | 2 +- .../packages/sdk/rollup-full-fat.config.mjs | 28 ++++ sdk/typescript/packages/sdk/scripts/build.sh | 7 + 37 files changed, 1047 insertions(+), 11 deletions(-) create mode 100644 sdk/typescript/examples/chrome-extension/README.md create mode 100644 sdk/typescript/examples/chrome-extension/manifest.json create mode 100644 sdk/typescript/examples/chrome-extension/package.json create mode 100644 sdk/typescript/examples/chrome-extension/popup.css create mode 100644 sdk/typescript/examples/chrome-extension/popup.html create mode 100644 sdk/typescript/examples/chrome-extension/src/dom-utils.js create mode 100644 sdk/typescript/examples/chrome-extension/src/main.js create mode 100644 sdk/typescript/examples/chrome-extension/webpack.config.js create mode 100644 sdk/typescript/examples/firefox-extension/.gitignore create mode 100644 sdk/typescript/examples/firefox-extension/README.md create mode 100644 sdk/typescript/examples/firefox-extension/manifest.json create mode 100644 sdk/typescript/examples/firefox-extension/package.json create mode 100644 sdk/typescript/examples/firefox-extension/popup.css create mode 100644 sdk/typescript/examples/firefox-extension/popup.html create mode 100644 sdk/typescript/examples/firefox-extension/src/background.js create mode 100644 sdk/typescript/examples/firefox-extension/src/dom-utils.js create mode 100644 sdk/typescript/examples/firefox-extension/src/popup.js create mode 100644 sdk/typescript/examples/firefox-extension/webpack.config.js delete mode 100644 sdk/typescript/examples/node-tester/plain-html/.babelrc delete mode 100644 sdk/typescript/examples/node-tester/plain-html/jest.config.js create mode 100644 sdk/typescript/examples/node-tester/react/README.md create mode 100644 sdk/typescript/examples/node-tester/react/index.html create mode 100644 sdk/typescript/examples/node-tester/react/package.json create mode 100644 sdk/typescript/examples/node-tester/react/src/App.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts create mode 100644 sdk/typescript/examples/node-tester/react/src/index.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/layouts/index.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/theme/theme.tsx create mode 100644 sdk/typescript/examples/node-tester/react/src/typesDefs.ts create mode 100644 sdk/typescript/examples/node-tester/react/tsconfig.json create mode 100644 sdk/typescript/packages/sdk/rollup-full-fat.config.mjs diff --git a/sdk/typescript/examples/chrome-extension/README.md b/sdk/typescript/examples/chrome-extension/README.md new file mode 100644 index 0000000000..8d7359e8c3 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/README.md @@ -0,0 +1,22 @@ +# Nym Chrome Extension Example + +This is an example of how Nym can be used within the context of a Chrome extension. + +## Running the example + +1. Copy a build of the Nym TypeScript SDK (ESM version) into `./sdk`. +2. Navigate to `chrome://extensions` in Google Chrome. +3. Enable "Developer mode" (top right of the page). +4. Click on "Load unpacked" (top left of the page). +5. Load this extension folder. + +## How does it work? + +The Nym Mixnet Client runs a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) that wraps +a WASM library that builds and encrypts Sphinx packets in the browser to send over the Nym mixnet: + +![Sphinx packet](../docs/worker.svg) + +The WASM code encrypts each layer of the Sphinx packet in the browser, before sending the Sphinx packet over a websocket to the ingress gateway: + +![Sphinx packet](../docs/sphinx.svg) diff --git a/sdk/typescript/examples/chrome-extension/manifest.json b/sdk/typescript/examples/chrome-extension/manifest.json new file mode 100644 index 0000000000..5f83d5c014 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/manifest.json @@ -0,0 +1,17 @@ +{ + "name": "Nym Chrome Extension Example", + "description": "An example demonstrating how to integrate the Nym TypeScript SDK in the context of a Google Chrome browser extension.", + "version": "1.0", + "manifest_version": 3, + "icons": { + "48": "icon.png" + }, + "content_security_policy": { + "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';" + }, + "action": { + "default_title": "Nym Chrome Extension Example", + "default_icon": "icon.png", + "default_popup": "popup.html" + } +} diff --git a/sdk/typescript/examples/chrome-extension/package.json b/sdk/typescript/examples/chrome-extension/package.json new file mode 100644 index 0000000000..cf9d9927d0 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/package.json @@ -0,0 +1,20 @@ +{ + "name": "chrome-extension", + "version": "1.0.0", + "description": "This is an example of how Nym can be used within the context of a Chrome extension.", + "main": "index.js", + "scripts": { + "build": "webpack" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "clean-webpack-plugin": "^4.0.0", + "copy-webpack-plugin": "^11.0.0", + "webpack": "^5.88.1", + "webpack-cli": "^5.1.4" + }, + "dependencies": { + "@nymproject/sdk": "^1.1.8" + } +} diff --git a/sdk/typescript/examples/chrome-extension/popup.css b/sdk/typescript/examples/chrome-extension/popup.css new file mode 100644 index 0000000000..491c7dc3c7 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/popup.css @@ -0,0 +1,8 @@ +body { + width: 800px; + min-height: 400px; +} + +#editdialog input { + width: 100%; +} \ No newline at end of file diff --git a/sdk/typescript/examples/chrome-extension/popup.html b/sdk/typescript/examples/chrome-extension/popup.html new file mode 100644 index 0000000000..9245988b60 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/popup.html @@ -0,0 +1,23 @@ + + + + + + + + +

    +

    +

    +

    +

    Send messages from your browser, through the mixnet, and to the recipient using the "send" button.

    +

    + Sent messages show in blue, received messages + show in green. +

    +
    +

    +
    +

    + + diff --git a/sdk/typescript/examples/chrome-extension/src/dom-utils.js b/sdk/typescript/examples/chrome-extension/src/dom-utils.js new file mode 100644 index 0000000000..322606c241 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/src/dom-utils.js @@ -0,0 +1,66 @@ +// dom-utils.js +// Contains utility functionality to help manipulate the DOM elements necessary to demonstrate the Nym example. + +/** + * Create a Sphinx packet and send it to the mixnet through the gateway node. + * + * Message and recipient are taken from the values in the user interface. + * + * @param {Client} nymClient the nym client to use for message sending + */ +async function sendMessageTo(nym) { + const message = document.getElementById('message').value; + const recipient = document.getElementById('recipient').value; + await nym.client.send({ + payload: { + message, + mimeType: 'text/plain' + }, + recipient + }); + displaySend(message); +} + +/** + * Display messages that have been sent up the websocket. Colours them blue. + * + * @param {string} message + */ +function displaySend(message) { + const timestamp = new Date().toISOString().substr(11, 12); + const sendDiv = document.createElement('div'); + const paragraph = document.createElement('p'); + paragraph.setAttribute('style', 'color: blue'); + const paragraphContent = document.createTextNode(`${timestamp} sent >>> ${message}`); + paragraph.appendChild(paragraphContent); + sendDiv.appendChild(paragraph); + document.getElementById('output')?.appendChild(sendDiv); +} + +/** + * Display received text messages in the browser. Colour them green. + * + * @param {string} message + */ +function displayReceived(message) { + const content = message; + const timestamp = new Date().toLocaleTimeString(); + const receivedDiv = document.createElement('div'); + const paragraph = document.createElement('p'); + paragraph.setAttribute('style', 'color: green'); + const paragraphContent = document.createTextNode(`${timestamp} received >>> ${content}`); + paragraph.appendChild(paragraphContent); + receivedDiv.appendChild(paragraph); + document.getElementById('output')?.appendChild(receivedDiv); +} + +/** + * Display the nymClient's sender address in the user interface + * + * @param {Client} nymClient + */ +function displaySenderAddress(address) { + document.getElementById('sender').value = address; +} + +export { sendMessageTo, displaySend, displayReceived , displaySenderAddress } \ No newline at end of file diff --git a/sdk/typescript/examples/chrome-extension/src/main.js b/sdk/typescript/examples/chrome-extension/src/main.js new file mode 100644 index 0000000000..5ead4f6c67 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/src/main.js @@ -0,0 +1,53 @@ +// main.js +// Simple example of how to load Nym's TypeScript SDK and bind it to a DOM. +// Look at dom-utils.js for the DOM utility functionality referenced here. + +// Import the Nym mixnet ESM module. +import { createNymMixnetClient } from '@nymproject/sdk'; + +// Import the DOM utility functionality. +import { displaySenderAddress, displayReceived, sendMessageTo } from './dom-utils.js'; + +async function main() { + // Initialize the Nym mixnet client. + let nymClient = await createNymMixnetClient(); + if (!nymClient) { + console.error('Oh no! Could not create client'); + return; + } + + const nymApiUrl = 'https://validator.nymtech.net/api'; + const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; + + // subscribe to connect event, so that we can show the client's address + nymClient.events.subscribeToConnected((e) => { + if (e.args.address) { + displaySenderAddress(e.args.address); + } + }); + + // subscribe to message received events and show any string messages received + nymClient.events.subscribeToTextMessageReceivedEvent((e) => { + displayReceived(e.args.payload); + }); + + const sendButton = document.querySelector('#send-button'); + if (sendButton) { + sendButton.onclick = function () { + if (nymClient) { + sendMessageTo(nymClient); + } + }; + } + + nymClient.events.subscribeToRawMessageReceivedEvent((e) => console.log('Received: ', e.args.payload)); + await nymClient.client.start({ + clientId: 'My awesome client', + nymApiUrl, + preferredGatewayIdentityKey, + }); +} + +window.addEventListener('DOMContentLoaded', () => { + main(); +}); diff --git a/sdk/typescript/examples/chrome-extension/webpack.config.js b/sdk/typescript/examples/chrome-extension/webpack.config.js new file mode 100644 index 0000000000..d1c7c473c7 --- /dev/null +++ b/sdk/typescript/examples/chrome-extension/webpack.config.js @@ -0,0 +1,25 @@ +// Webpack configuration for the Chrome extension example + +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + main: './src/main.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CleanWebpackPlugin(), + new CopyWebpackPlugin({ + patterns: [ + 'manifest.json', + 'popup.html', + { from: path.resolve(__dirname, '../../../../assets/favicon/favicon.png'), to: 'icon.png' }, + ], + }), + ], +}; diff --git a/sdk/typescript/examples/firefox-extension/.gitignore b/sdk/typescript/examples/firefox-extension/.gitignore new file mode 100644 index 0000000000..6e8096e78b --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/.gitignore @@ -0,0 +1 @@ +sdk/index.js \ No newline at end of file diff --git a/sdk/typescript/examples/firefox-extension/README.md b/sdk/typescript/examples/firefox-extension/README.md new file mode 100644 index 0000000000..27678813c6 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/README.md @@ -0,0 +1,35 @@ +# Nym Firefox Extension Example + +This is an example of how Nym can be used within the context of a Mozilla Firefox extension. + +## Running the example + +First, build the Nym SDK: + +From the SDK directory `sdk/typescript/packages/sdk` run: + +```js +npm run build:local +``` + +Then, from the example directory `sdk/typescript/examples/firefox-extension` run: + +```js +npm install +npm run build +``` + +## Workers + +Firefox browser extensions cannot run inline web workers. In order to overcome this limitation, the Nym Firefox Extension Example imports workers from the SDK and uses Webpack's `worker-loader` to allow the worker's to be bundled inline into the extension. In order for webpack to include the workers in the build, they are imported as modules in the `src/index.js` file: + +## How does it work? + +The Nym Mixnet Client runs a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) that wraps +a WASM library that builds and encrypts Sphinx packets in the browser to send over the Nym mixnet: + +![Sphinx packet](../docs/worker.svg) + +The WASM code encrypts each layer of the Sphinx packet in the browser, before sending the Sphinx packet over a websocket to the ingress gateway: + +![Sphinx packet](../docs/sphinx.svg) diff --git a/sdk/typescript/examples/firefox-extension/manifest.json b/sdk/typescript/examples/firefox-extension/manifest.json new file mode 100644 index 0000000000..5829265a88 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 3, + "name": "Nym Firefox Extension Example", + "version": "1.0", + "description": "An example demonstrating how to integrate the Nym TypeScript SDK in the context of a Mozilla Firefox browser extension.", + "icons": { + "48": "icon.png" + }, + "permissions": [], + "content_security_policy": { + "extension_pages": "script-src 'self' 'wasm-unsafe-eval';" + }, + "background": { + "scripts": ["background.js"] + }, + "action": { + "default_icon": { + "32": "icon.png" + }, + "default_title": "Nym Firefox Extension Example", + "default_popup": "popup.html" + } +} diff --git a/sdk/typescript/examples/firefox-extension/package.json b/sdk/typescript/examples/firefox-extension/package.json new file mode 100644 index 0000000000..70160f5150 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/package.json @@ -0,0 +1,19 @@ +{ + "name": "firefox-extension", + "version": "1.0.0", + "description": "This is an example of how Nym can be used within the context of a Firefox extension.", + "main": "index.js", + "author": "", + "license": "ISC", + "devDependencies": { + "copy-webpack-plugin": "^11.0.0", + "webpack": "^5.88.1", + "webpack-cli": "^5.1.4" + }, + "scripts": { + "build": "yarn webpack" + }, + "dependencies": { + "worker-loader": "^3.0.8" + } +} diff --git a/sdk/typescript/examples/firefox-extension/popup.css b/sdk/typescript/examples/firefox-extension/popup.css new file mode 100644 index 0000000000..491c7dc3c7 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/popup.css @@ -0,0 +1,8 @@ +body { + width: 800px; + min-height: 400px; +} + +#editdialog input { + width: 100%; +} \ No newline at end of file diff --git a/sdk/typescript/examples/firefox-extension/popup.html b/sdk/typescript/examples/firefox-extension/popup.html new file mode 100644 index 0000000000..976e0c54f4 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/popup.html @@ -0,0 +1,23 @@ + + + + + + + + +

    +

    +

    +

    +

    Send messages from your browser, through the mixnet, and to the recipient using the "send" button.

    +

    + Sent messages show in blue, received messages + show in green. +

    +
    +

    +
    +

    + + diff --git a/sdk/typescript/examples/firefox-extension/src/background.js b/sdk/typescript/examples/firefox-extension/src/background.js new file mode 100644 index 0000000000..c0a6ce8a35 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/src/background.js @@ -0,0 +1,107 @@ +// main.js +// Simple example of how to load Nym's TypeScript SDK and bind it to a DOM. +// Look at dom-utils.js for the DOM utility functionality referenced here. + +// Import the Nym mixnet ESM module. +// Import The web workers for the Nym mixnet ESM module.These are required for to run the Nym mixnet client. + +import { createNymMixnetClient } from '../../../packages/sdk/dist/full-fat/index.js'; +import '../../../packages/sdk/dist/full-fat/web-worker-0.js'; +import '../../../packages/sdk/dist/full-fat/web-worker-1.js'; + +const backgroundState = { + isReady: false, + address: '', + recipient: '', + messageLog: [], +}; + +async function initBackground() { + // Initialize the Nym mixnet client. + let nymClient = await createNymMixnetClient().catch((err) => { + console.log(err); + }); + if (!nymClient) { + console.error('Oh no! Could not create client'); + return; + } + const nymApiUrl = 'https://validator.nymtech.net/api'; + const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; + + // subscribe to connect event, so that we can show the client's address + nymClient.events.subscribeToConnected((e) => { + if (e.args.address) { + backgroundState.address = e.args.address; + browser.runtime.sendMessage({ + type: 'displaySenderAddress', + message: backgroundState.address, + }); + } + }); + + // subscribe to message received events and show any string messages received + nymClient.events.subscribeToTextMessageReceivedEvent((e) => { + backgroundState.messageLog.push({ + type: 'received', + message: e.args.payload, + }); + browser.runtime.sendMessage({ + type: 'displayReceived', + message: e.args.payload, + }); + }); + + nymClient.events.subscribeToRawMessageReceivedEvent((e) => console.log('Received: ', e.args.payload)); + await nymClient.client.start({ + clientId: 'My awesome client', + nymApiUrl, + preferredGatewayIdentityKey, + }); + browser.runtime.onMessage.addListener(async (data) => { + switch (data.type) { + case 'nymClientSendMessage': + if (nymClient) { + await nymClient.client.send({ + payload: { + message: data.message, + mimeType: 'text/plain', + }, + recipient: data.recipient, + }); + backgroundState.messageLog.push({ + type: 'sent', + message: data.message, + }); + break; + } + } + }); + backgroundState.isReady = true; +} + +window.addEventListener('DOMContentLoaded', () => { + browser.runtime.onMessage.addListener((data) => { + switch (data.type) { + case 'popupReady': + if (backgroundState.isReady) { + browser.runtime.sendMessage({ + type: 'displaySenderAddress', + message: backgroundState.address, + }); + browser.runtime.sendMessage({ + type: 'displayMessageLog', + message: backgroundState.messageLog, + }); + browser.runtime.sendMessage({ + type: 'updateRecipient', + message: backgroundState.recipient, + }); + } else { + initBackground(); + } + break; + case 'updateRecipient': + backgroundState.recipient = data.message; + } + }); +}); diff --git a/sdk/typescript/examples/firefox-extension/src/dom-utils.js b/sdk/typescript/examples/firefox-extension/src/dom-utils.js new file mode 100644 index 0000000000..859dcdac2c --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/src/dom-utils.js @@ -0,0 +1,74 @@ +// dom-utils.js +// Contains utility functionality to help manipulate the DOM elements necessary to demonstrate the Nym example. + +/** + * Create a Sphinx packet and send it to the mixnet through the gateway node. + * + * Message and recipient are taken from the values in the user interface. + * + * @param {Client} nymClient the nym client to use for message sending + */ +async function sendMessageTo() { + const message = document.getElementById('message').value; + const recipient = document.getElementById('recipient').value; + browser.runtime.sendMessage({ + type: 'nymClientSendMessage', + message, + recipient, + }); + displaySend(message); +} + +/** + * Display messages that have been sent up the websocket. Colours them blue. + * + * @param {string} message + */ +function displaySend(message) { + const timestamp = new Date().toISOString().substr(11, 12); + const sendDiv = document.createElement('div'); + const paragraph = document.createElement('p'); + paragraph.setAttribute('style', 'color: blue'); + const paragraphContent = document.createTextNode(`${timestamp} sent >>> ${message}`); + paragraph.appendChild(paragraphContent); + sendDiv.appendChild(paragraph); + document.getElementById('output')?.appendChild(sendDiv); +} + +/** + * Display received text messages in the browser. Colour them green. + * + * @param {string} message + */ +function displayReceived(message) { + const content = message; + const timestamp = new Date().toLocaleTimeString(); + const receivedDiv = document.createElement('div'); + const paragraph = document.createElement('p'); + paragraph.setAttribute('style', 'color: green'); + const paragraphContent = document.createTextNode(`${timestamp} received >>> ${content}`); + paragraph.appendChild(paragraphContent); + receivedDiv.appendChild(paragraph); + document.getElementById('output')?.appendChild(receivedDiv); +} + +/** + * Display the nymClient's sender address in the user interface + * + * @param {Client} nymClient + */ +function displaySenderAddress(address) { + document.getElementById('sender').value = address; +} + +function displayMessageLog(messageLog) { + for (let i = 0; i < messageLog.length; i++) { + if (messageLog[i].type === 'sent') { + displaySend(messageLog[i].message); + } else if (messageLog[i].type === 'received') { + displayReceived(messageLog[i].message); + } + } +} + +export { sendMessageTo, displaySend, displayReceived, displaySenderAddress, displayMessageLog }; diff --git a/sdk/typescript/examples/firefox-extension/src/popup.js b/sdk/typescript/examples/firefox-extension/src/popup.js new file mode 100644 index 0000000000..8126f21827 --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/src/popup.js @@ -0,0 +1,40 @@ +// Import the DOM utility functionality. +import { displaySenderAddress, displayReceived, sendMessageTo, displayMessageLog } from './dom-utils.js'; + +window.addEventListener('DOMContentLoaded', () => { + const sendButton = document.querySelector('#send-button'); + if (sendButton) { + sendButton.onclick = function () { + sendMessageTo(); + }; + } + const recipient = document.getElementById('recipient'); + recipient.onchange = () => { + browser.runtime.sendMessage({ + type: 'updateRecipient', + message: recipient.value, + }); + }; + browser.runtime.onMessage.addListener((data) => { + switch (data.type) { + case 'displaySenderAddress': + displaySenderAddress(data.message); + break; + case 'displayReceived': + displayReceived(data.message); + break; + case 'sendMessageTo': + sendMessageTo(data.message); + break; + case 'displayMessageLog': + displayMessageLog(data.message); + break; + case 'updateRecipient': + recipient.value = data.message; + } + }); + browser.runtime.sendMessage({ + type: 'popupReady', + message: '', + }); +}); diff --git a/sdk/typescript/examples/firefox-extension/webpack.config.js b/sdk/typescript/examples/firefox-extension/webpack.config.js new file mode 100644 index 0000000000..26bd5d679c --- /dev/null +++ b/sdk/typescript/examples/firefox-extension/webpack.config.js @@ -0,0 +1,38 @@ +// Webpack configuration for the Firefox extension example + +const path = require('path'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const { CleanWebpackPlugin } = require('clean-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + background: './src/background.js', + popup: './src/popup.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + }, + plugins: [ + new CleanWebpackPlugin(), + new CopyWebpackPlugin({ + patterns: [ + 'manifest.json', + 'popup.html', + { from: path.resolve(__dirname, '../../../../assets/favicon/favicon.png'), to: 'icon.png' }, + ], + }), + ], + module: { + rules: [ + { + test: /web-worker.*\.js$/, + loader: 'worker-loader', + options: { + filename: '[name].js', + inline: 'fallback', + }, + }, + ], + }, +}; diff --git a/sdk/typescript/examples/node-tester/parcel/src/index.html b/sdk/typescript/examples/node-tester/parcel/src/index.html index a7bd3057e7..acd8174db6 100644 --- a/sdk/typescript/examples/node-tester/parcel/src/index.html +++ b/sdk/typescript/examples/node-tester/parcel/src/index.html @@ -4,7 +4,7 @@ - Nym WebAssembly Demo + Nym Node Tester Demo diff --git a/sdk/typescript/examples/node-tester/plain-html/.babelrc b/sdk/typescript/examples/node-tester/plain-html/.babelrc deleted file mode 100644 index 85e1f1ba26..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@babel/env", "@babel/react"] -} \ No newline at end of file diff --git a/sdk/typescript/examples/node-tester/plain-html/jest.config.js b/sdk/typescript/examples/node-tester/plain-html/jest.config.js deleted file mode 100644 index e86e13bab9..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -}; diff --git a/sdk/typescript/examples/node-tester/plain-html/src/index.html b/sdk/typescript/examples/node-tester/plain-html/src/index.html index ccac6e2365..fc536c636c 100644 --- a/sdk/typescript/examples/node-tester/plain-html/src/index.html +++ b/sdk/typescript/examples/node-tester/plain-html/src/index.html @@ -4,7 +4,7 @@ - Nym WebAssembly Demo + Nym Node Tester Demo diff --git a/sdk/typescript/examples/node-tester/react/README.md b/sdk/typescript/examples/node-tester/react/README.md new file mode 100644 index 0000000000..13d4a79db3 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/README.md @@ -0,0 +1,14 @@ +# Nym Node Tester - React + +This is an example of using the Nym Mixnet node tester. + +You can use this example as a seed for a new project. + +## Running the example + +Try out the node tester app by running: + +``` +npm install +npm start +``` diff --git a/sdk/typescript/examples/node-tester/react/index.html b/sdk/typescript/examples/node-tester/react/index.html new file mode 100644 index 0000000000..193ccdcbd1 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/index.html @@ -0,0 +1,13 @@ + + + + + + + Nym Node Tester Example + + +
    + + + diff --git a/sdk/typescript/examples/node-tester/react/package.json b/sdk/typescript/examples/node-tester/react/package.json new file mode 100644 index 0000000000..d453a0c291 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/package.json @@ -0,0 +1,19 @@ +{ + "name": "@nymproject/sdk-example-node-tester-react", + "description": "An example project that uses WASM node tester and React", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.14.0", + "@mui/material": "^5.14.0", + "@nymproject/sdk": "1", + "parcel": "^2.9.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "scripts": { + "start": "parcel index.html" + } +} diff --git a/sdk/typescript/examples/node-tester/react/src/App.tsx b/sdk/typescript/examples/node-tester/react/src/App.tsx new file mode 100644 index 0000000000..eb0bd1927a --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/App.tsx @@ -0,0 +1,127 @@ +import React, { useState } from 'react'; +import { + Button, + Card, + CardActions, + CardContent, + CardHeader, + CircularProgress, + Grid, + List, + ListItem, + ListItemText, + TextField, + Typography, +} from '@mui/material'; +import { NodeTestResultResponse } from '@nymproject/sdk'; +import { ScoreIndicator } from 'src/components/ScoreIndicator'; +import { useNodeTesterClient } from 'src/hooks/useNodeTesterClient'; +import { BasicPageLayout } from 'src/layouts'; +import { TestStatusLabel } from 'src/components/TestStatusLabel'; +import Icon from '../../../../../../assets/appicon/appicon.png'; + +export const App = () => { + const { testState, error, testNode, disconnectFromGateway, reconnectToGateway } = useNodeTesterClient(); + const [mixnodeIdentity, setMixnodeIdentity] = useState(''); + const [results, setResults] = React.useState(); + + console.log({ testState, error, testNode }); + + const handleTestNode = async () => { + setResults(undefined); + try { + const result = await testNode(mixnodeIdentity); + setResults(result); + } catch (e) { + console.error(e); + } + }; + + return ( + + + Nym Mixnode Testnet Node Tester} + action={} + avatar={} + /> + + + + + + + + + + + + + + + + + + + + + + + + { + setMixnodeIdentity(e.target.value); + }} + fullWidth + /> + + + + + + + + + + + + + + + ); +}; diff --git a/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx b/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx new file mode 100644 index 0000000000..6527edeb48 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { Box, CircularProgress, CircularProgressProps, Stack, Typography } from '@mui/material'; + +const getPerformanceDescriptionAndColor = (score: number) => { + const res: { description: string; color: CircularProgressProps['color'] } = { description: '', color: 'warning' }; + + if (score >= 90) { + res.description = 'Reliable node'; + res.color = 'success'; + } + + if (score >= 75 && score < 90) { + res.description = 'Average node'; + res.color = 'warning'; + } + + if (score > 0 && score < 75) { + res.description = 'Unreliable node'; + res.color = 'error'; + } + + return res; +}; + +export const ScoreIndicator = ({ score }) => { + const { color } = getPerformanceDescriptionAndColor(score); + return ( + + + + + + {Math.round(score)}% + + Performance Score + + + ); +}; diff --git a/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx b/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx new file mode 100644 index 0000000000..558677fce7 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Chip } from '@mui/material'; +import { HourglassTop, ErrorOutline, CheckCircleOutline, WarningAmber } from '@mui/icons-material'; +import { TestState } from 'src/hooks/useNodeTesterClient'; + +const getColor = (state: TestState) => { + switch (state) { + case 'Connecting': + return 'warning'; + case 'Error': + return 'error'; + case 'Ready': + return 'success'; + default: + return 'warning'; + } +}; + +const getIcon = (state: TestState) => { + switch (state) { + case 'Connecting': + return ; + case 'Error': + return ; + case 'Ready': + return ; + default: + return ; + } +}; + +export const TestStatusLabel = ({ state }: { state: TestState }) => ( + +); diff --git a/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts b/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts new file mode 100644 index 0000000000..fcd6f92937 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts @@ -0,0 +1,71 @@ +import { useState, useEffect } from 'react'; +import { createNodeTesterClient, NodeTester } from '@nymproject/sdk'; + +export type TestState = 'Ready' | 'Connecting' | 'Disconnected' | 'Disconnecting' | 'Error' | 'Testing' | 'Stopped'; + +export const useNodeTesterClient = () => { + const [client, setClient] = useState(); + const [error, setError] = useState(); + const [testState, setTestState] = useState('Disconnected'); + + const createClient = async () => { + setTestState('Connecting'); + try { + const validator = 'https://validator.nymtech.net/api'; + const nodeTesterClient = await createNodeTesterClient(); + + await nodeTesterClient.tester.init(validator); + setClient(nodeTesterClient); + } catch (e) { + console.log(e); + setError('Failed to load node tester client, please try again'); + } finally { + setTestState('Ready'); + } + }; + + useEffect(() => { + createClient(); + }, []); + + const testNode = !client + ? undefined + : async (mixnodeIdentity: string) => { + try { + setTestState('Testing'); + const result = await client.tester.startTest(mixnodeIdentity); + setTestState('Ready'); + return result; + } catch (e) { + console.log(e); + setError('Failed to test node, please try again'); + setTestState('Error'); + } + }; + + const disconnectFromGateway = !client + ? undefined + : async () => { + setTestState('Disconnecting'); + await client.tester.disconnectFromGateway(); + setTestState('Disconnected'); + }; + + const reconnectToGateway = !client + ? undefined + : async () => { + setTestState('Connecting'); + await client.tester.reconnectToGateway(); + setTestState('Ready'); + }; + + const terminateWorker = !client + ? undefined + : async () => { + setTestState('Disconnecting'); + await client.terminate(); + setTestState('Disconnected'); + }; + + return { testNode, disconnectFromGateway, reconnectToGateway, terminateWorker, testState, error }; +}; diff --git a/sdk/typescript/examples/node-tester/react/src/index.tsx b/sdk/typescript/examples/node-tester/react/src/index.tsx new file mode 100644 index 0000000000..77d3da3be1 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { App } from './App'; +import { NymThemeProvider } from './theme/theme'; + +const rootDOMElem = document.getElementById('root'); +if (!rootDOMElem) throw new Error('Root element not found'); + +const root = createRoot(rootDOMElem); +root.render( + + + , +); diff --git a/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx b/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx new file mode 100644 index 0000000000..1a38d6a350 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx @@ -0,0 +1,6 @@ +import React from 'react'; +import { Container } from '@mui/material'; + +export const BasicPageLayout = ({ children }: { children: React.ReactNode }) => ( + {children} +); diff --git a/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx b/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx new file mode 100644 index 0000000000..3f5d35fdf9 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { createTheme, ThemeProvider } from '@mui/material/styles'; +import { CssBaseline } from '@mui/material'; + +export const NymThemeProvider = ({ children }: { children: React.ReactNode }) => { + const theme = createTheme({ + palette: { + mode: 'dark', + primary: { + main: '#FB6E4E', + }, + success: { + main: '#21D073', + }, + background: { + default: '#1D2125', + paper: '#292E34', + }, + }, + }); + + return ( + + + {children} + + ); +}; diff --git a/sdk/typescript/examples/node-tester/react/src/typesDefs.ts b/sdk/typescript/examples/node-tester/react/src/typesDefs.ts new file mode 100644 index 0000000000..dd84df40a4 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/src/typesDefs.ts @@ -0,0 +1,4 @@ +declare module '*.png' { + const content: any; + export default content; +} diff --git a/sdk/typescript/examples/node-tester/react/tsconfig.json b/sdk/typescript/examples/node-tester/react/tsconfig.json new file mode 100644 index 0000000000..272e623d99 --- /dev/null +++ b/sdk/typescript/examples/node-tester/react/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "jsx": "react", + "baseUrl": ".", + "paths": { + "react": ["node_modules/react"], + "react-dom": ["node_modules/react-dom"] + }, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true + }, + "include": ["src"], + "paths": { + "@assets/*": ["../../../../../../assets"] + } +} diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index de6d16554d..3bb41184b5 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@npmcli/node-gyp": "^3.0.0", - "@nymproject/nym-client-wasm": "1", + "@nymproject/nym-client-wasm": "1.0.0", "comlink": "^4.3.1", "lerna": "^6.6.2", "node-gyp": "^9.3.1" diff --git a/sdk/typescript/packages/sdk/rollup-full-fat.config.mjs b/sdk/typescript/packages/sdk/rollup-full-fat.config.mjs new file mode 100644 index 0000000000..f9d3739df2 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-full-fat.config.mjs @@ -0,0 +1,28 @@ +// This is the rollup config for the full-fat SDK package. +// The config is similar to the esm config, but exports web workers as separate files. +// This can be necessary for implentations that do not support inline web workers. + +import typescript from '@rollup/plugin-typescript'; +import resolve from '@rollup/plugin-node-resolve'; +import webWorkerLoader from 'rollup-plugin-web-worker-loader'; + +const extensions = ['.js', '.jsx', '.ts', '.tsx']; + +export default { + input: 'src/index.ts', + output: { + dir: 'dist/full-fat', + format: 'es', + }, + plugins: [ + webWorkerLoader({ + targetPlatform: 'browser', + inline: false, + }), + resolve({ extensions }), + typescript({ + exclude: ['mixnet/wasm/worker.ts', 'mixnet/node-tester/worker.ts'], + compilerOptions: { outDir: 'dist/full-fat' }, + }), + ], +}; diff --git a/sdk/typescript/packages/sdk/scripts/build.sh b/sdk/typescript/packages/sdk/scripts/build.sh index d2763969e7..05800b5c9d 100755 --- a/sdk/typescript/packages/sdk/scripts/build.sh +++ b/sdk/typescript/packages/sdk/scripts/build.sh @@ -48,6 +48,13 @@ rollup -c rollup-esm.config.mjs # build the SDK as a CommonJS bundle rollup -c rollup-cjs.config.mjs +#------------------------------------------------------- +# FULL FAT +#------------------------------------------------------- + +# build the SDK as a ESM bundle +rollup -c rollup-full-fat.config.mjs + #------------------------------------------------------- # CLEAN UP #------------------------------------------------------- From 9d5b5829088dde39e3ececcaf487c1ff0ffd4494 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Tue, 18 Jul 2023 14:12:00 +0100 Subject: [PATCH 22/59] SDK - fix unsubscribe function for events (#3659) Co-authored-by: Mark Sinclair --- sdk/typescript/packages/sdk/.babelrc | 3 + sdk/typescript/packages/sdk/jest.config.mjs | 15 + sdk/typescript/packages/sdk/package.json | 15 +- .../packages/sdk/src/mixnet/wasm/index.ts | 60 +- .../sdk/src/mixnet/wasm/subscriptions.test.ts | 98 +++ .../sdk/src/mixnet/wasm/subscriptions.ts | 69 ++ .../packages/sdk/tsconfig.jest.json | 42 + yarn.lock | 778 +++++++++++++++++- 8 files changed, 1021 insertions(+), 59 deletions(-) create mode 100644 sdk/typescript/packages/sdk/.babelrc create mode 100644 sdk/typescript/packages/sdk/jest.config.mjs create mode 100644 sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.test.ts create mode 100644 sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.ts create mode 100644 sdk/typescript/packages/sdk/tsconfig.jest.json diff --git a/sdk/typescript/packages/sdk/.babelrc b/sdk/typescript/packages/sdk/.babelrc new file mode 100644 index 0000000000..0ef5ffc214 --- /dev/null +++ b/sdk/typescript/packages/sdk/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/env"] +} diff --git a/sdk/typescript/packages/sdk/jest.config.mjs b/sdk/typescript/packages/sdk/jest.config.mjs new file mode 100644 index 0000000000..ed5b112c72 --- /dev/null +++ b/sdk/typescript/packages/sdk/jest.config.mjs @@ -0,0 +1,15 @@ +import preset from 'ts-jest/presets/index.js' + +/** @type {import('ts-jest').JestConfigWithTsJest} */ +export default { + ...preset.defaults, + transform: { + '^.+\\.(ts|tsx)$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.jest.json', + useESM: true, + }, + ], + }, +} diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index 3bb41184b5..c156bd5876 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -27,7 +27,8 @@ "prebuild:dev": "yarn build:dependencies", "build:dev": "yarn build:dev:only-this", "build:dev:only-this": "scripts/build.sh", - "build:local": "run-s build:dependencies:nym-client-wasm build:dev:only-this" + "build:local": "run-s build:dependencies:nym-client-wasm build:dev:only-this", + "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache" }, "dependencies": { "@npmcli/node-gyp": "^3.0.0", @@ -37,6 +38,11 @@ "node-gyp": "^9.3.1" }, "devDependencies": { + "@babel/core": "^7.15.0", + "@babel/plugin-transform-async-to-generator": "^7.14.5", + "@babel/preset-env": "^7.15.0", + "@babel/preset-react": "^7.14.5", + "@babel/preset-typescript": "^7.15.0", "@nymproject/eslint-config-react-typescript": "^1.0.0", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-inject": "^5.0.3", @@ -48,6 +54,8 @@ "@rollup/plugin-wasm": "^6.1.1", "@typescript-eslint/eslint-plugin": "^5.13.0", "@typescript-eslint/parser": "^5.13.0", + "@types/jest": "^27.0.1", + "@types/node": "^16.7.13", "eslint": "^8.10.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", @@ -63,6 +71,9 @@ "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-web-worker-loader": "^1.6.1", - "typescript": "^4.8.4" + "typescript": "^4.8.4", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "ts-loader": "^9.4.2" } } diff --git a/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts b/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts index b60550aee0..1b80d844e8 100644 --- a/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts +++ b/sdk/typescript/packages/sdk/src/mixnet/wasm/index.ts @@ -3,16 +3,16 @@ import InlineWasmWebWorker from 'web-worker:./worker'; import { BinaryMessageReceivedEvent, ConnectedEvent, - EventHandlerFn, EventKinds, IWebWorker, IWebWorkerAsync, IWebWorkerEvents, LoadedEvent, MimeTypes, - StringMessageReceivedEvent, RawMessageReceivedEvent, + StringMessageReceivedEvent, } from './types'; +import { createSubscriptions } from './subscriptions'; /** * Client for the Nym mixnet. @@ -33,25 +33,13 @@ export const createNymMixnetClient = async (options?: { // eslint-disable-next-line @typescript-eslint/no-use-before-define const worker = await createWorker(); - // stores the subscriptions for events - const subscriptions: { - [key: string]: Array>; - } = {}; - - /** - * Helper method to get typed subscriptions - */ - const getSubscriptions = (key: EventKinds): Array> => { - if (!subscriptions[key]) { - subscriptions[key] = []; - } - return subscriptions[key] as Array>; - }; + const subscriptions = createSubscriptions(); + const { getSubscriptions, addSubscription } = subscriptions; // listen to messages from the worker, parse them and let the subscribers handle them, catching any unhandled exceptions worker.addEventListener('message', (msg) => { if (msg.data && msg.data.kind) { - const subscribers = subscriptions[msg.data.kind]; + const subscribers = getSubscriptions(msg.data.kind); (subscribers || []).forEach((s) => { try { // let the subscriber handle the message @@ -66,36 +54,14 @@ export const createNymMixnetClient = async (options?: { // manage the subscribers, returning self-unsubscribe methods const events: IWebWorkerEvents = { - subscribeToConnected: (handler) => { - getSubscriptions(EventKinds.Connected).push(handler); - return () => { - getSubscriptions(EventKinds.Connected).unshift(handler); - }; - }, - subscribeToLoaded: (handler) => { - getSubscriptions(EventKinds.Loaded).push(handler); - return () => { - getSubscriptions(EventKinds.Loaded).unshift(handler); - }; - }, - subscribeToTextMessageReceivedEvent: (handler) => { - getSubscriptions(EventKinds.StringMessageReceived).push(handler); - return () => { - getSubscriptions(EventKinds.StringMessageReceived).unshift(handler); - }; - }, - subscribeToBinaryMessageReceivedEvent: (handler) => { - getSubscriptions(EventKinds.BinaryMessageReceived).push(handler); - return () => { - getSubscriptions(EventKinds.BinaryMessageReceived).unshift(handler); - }; - }, - subscribeToRawMessageReceivedEvent: (handler) => { - getSubscriptions(EventKinds.RawMessageReceived).push(handler); - return () => { - getSubscriptions(EventKinds.RawMessageReceived).unshift(handler); - }; - }, + subscribeToConnected: (handler) => addSubscription(EventKinds.Connected, handler), + subscribeToLoaded: (handler) => addSubscription(EventKinds.Loaded, handler), + subscribeToTextMessageReceivedEvent: (handler) => + addSubscription(EventKinds.StringMessageReceived, handler), + subscribeToBinaryMessageReceivedEvent: (handler) => + addSubscription(EventKinds.BinaryMessageReceived, handler), + subscribeToRawMessageReceivedEvent: (handler) => + addSubscription(EventKinds.RawMessageReceived, handler), }; // let comlink handle interop with the web worker diff --git a/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.test.ts b/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.test.ts new file mode 100644 index 0000000000..49e72ed988 --- /dev/null +++ b/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.test.ts @@ -0,0 +1,98 @@ +import { createSubscriptions } from './subscriptions'; +import { EventKinds, MimeTypes, StringMessageReceivedEvent } from './types'; + +describe('wasm subscription manager', () => { + test('works with default values', () => { + const { getSubscriptions, fireEvent, addSubscription } = createSubscriptions(); + + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(0); + + // the event should fire and not fail + fireEvent(EventKinds.StringMessageReceived, {}); + + // mock a handler, fire events and check that it was called + const mockHandler = jest.fn(); + addSubscription(EventKinds.StringMessageReceived, mockHandler); + fireEvent(EventKinds.StringMessageReceived, {}); + expect(mockHandler).toHaveBeenCalled(); + }); + + test('adding and removing subscriptions works as expected', () => { + const { addSubscription, getSubscriptions, fireEvent } = createSubscriptions(); + + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(0); + + const callStats: number[] = [0, 0, 0]; + + const showDebug = false; + + const handler1 = (e: StringMessageReceivedEvent) => { + if (showDebug) { + console.log('handler1', e); + } + callStats[0] += 1; + }; + const handler2 = (e: StringMessageReceivedEvent) => { + if (showDebug) { + console.log('handler2', e); + } + callStats[1] += 1; + }; + const handler3 = (e: StringMessageReceivedEvent) => { + if (showDebug) { + console.log('handler3', e); + } + callStats[2] += 1; + }; + + const unsubcribeFn1 = addSubscription(EventKinds.StringMessageReceived, handler1); + const unsubcribeFn2 = addSubscription(EventKinds.StringMessageReceived, handler2); + const unsubcribeFn3 = addSubscription(EventKinds.StringMessageReceived, handler3); + + const event: StringMessageReceivedEvent = { + kind: EventKinds.StringMessageReceived, + args: { + payload: 'Testing', + mimeType: MimeTypes.TextPlain, + payloadRaw: new Uint8Array(), + }, + }; + + // fire and expect all handlers to get message + fireEvent(EventKinds.StringMessageReceived, event); + expect(callStats[0]).toBe(1); + expect(callStats[1]).toBe(1); + expect(callStats[2]).toBe(1); + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(3); + + // unscribe and fire again + unsubcribeFn2(); + fireEvent(EventKinds.StringMessageReceived, event); + expect(callStats[0]).toBe(2); + expect(callStats[1]).toBe(1); + expect(callStats[2]).toBe(2); + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(2); + + // unscribe and fire again + unsubcribeFn3(); + fireEvent(EventKinds.StringMessageReceived, event); + expect(callStats[0]).toBe(3); + expect(callStats[1]).toBe(1); + expect(callStats[2]).toBe(2); + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(1); + + // unscribe and fire again + unsubcribeFn1(); + fireEvent(EventKinds.StringMessageReceived, event); + expect(callStats[0]).toBe(3); + expect(callStats[1]).toBe(1); + expect(callStats[2]).toBe(2); + expect(getSubscriptions(EventKinds.StringMessageReceived)).toHaveLength(0); + + // nothing is subscribed, so fire again and check + fireEvent(EventKinds.StringMessageReceived, event); + expect(callStats[0]).toBe(3); + expect(callStats[1]).toBe(1); + expect(callStats[2]).toBe(2); + }); +}); diff --git a/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.ts b/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.ts new file mode 100644 index 0000000000..d819591f8b --- /dev/null +++ b/sdk/typescript/packages/sdk/src/mixnet/wasm/subscriptions.ts @@ -0,0 +1,69 @@ +import type { EventHandlerFn } from './types'; +import { EventKinds } from './types'; + +type ISubscriptions = { + [key: string]: Array>; +}; + +/** + * Creates a subscription manager. + */ +export const createSubscriptions = () => { + // stores the subscriptions for events + const subscriptions: ISubscriptions = {}; + + /** + * Helper method to get typed subscriptions. + */ + const getSubscriptions = (key: EventKinds): Array> => { + if (!subscriptions[key]) { + subscriptions[key] = []; + } + return subscriptions[key] as Array>; + }; + + /** + * Remove a subscription. + */ + const removeSubscription = (key: EventKinds, handler: EventHandlerFn) => { + if (!subscriptions[key]) { + subscriptions[key] = []; + } + const items: Array> = (subscriptions[key] as Array>).filter( + (h) => h !== handler, + ); + subscriptions[key] = items; + }; + + /** + * Add typed subscription. + */ + const addSubscription = (key: EventKinds, handler: EventHandlerFn) => { + getSubscriptions(key).push(handler as EventHandlerFn); + + return () => { + removeSubscription(key, handler); + }; + }; + + /** + * Fires an event. + */ + const fireEvent = (key: EventKinds, event: E) => { + getSubscriptions(key).forEach((handler) => { + try { + handler(event); + } catch (e: any) { + console.error(`Unhandled exception in handler for ${key}: `, e); + } + }); + }; + + return { + getSubscriptions, + addSubscription, + removeSubscription, + fireEvent, + subscriptions, + }; +}; diff --git a/sdk/typescript/packages/sdk/tsconfig.jest.json b/sdk/typescript/packages/sdk/tsconfig.jest.json new file mode 100644 index 0000000000..16e94d82b5 --- /dev/null +++ b/sdk/typescript/packages/sdk/tsconfig.jest.json @@ -0,0 +1,42 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "lib": [ + "es2021", + "dom", + "dom.iterable", + "esnext", + "webworker" + ], + "module": "CommonJS", + "target": "es5", + "strict": true, + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "declaration": true, + "baseUrl": ".", + "esModuleInterop": true, + "allowJs": true + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "jest.*", + "webpack.config.js", + "webpack.prod.js", + "webpack.common.js", + "node_modules", + "**/node_modules", + "dist", + "**/dist", + "scripts", + "jest", + "__tests__", + "**/__tests__", + "__jest__", + "**/__jest__", + "config/*" + ] +} diff --git a/yarn.lock b/yarn.lock index c223bce5af..8c6092b23f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,6 +39,11 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== +"@babel/compat-data@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.6.tgz#15606a20341de59ba02cd2fcc5086fcbe73bf544" + integrity sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg== + "@babel/core@7.12.9": version "7.12.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" @@ -82,6 +87,27 @@ json5 "^2.2.2" semver "^6.3.0" +"@babel/core@^7.11.6": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.8.tgz#386470abe884302db9c82e8e5e87be9e46c86785" + integrity sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.22.5", "@babel/generator@^7.7.2": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" @@ -92,6 +118,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.7.tgz#a6b8152d5a621893f2c9dacf9a4e286d520633d5" + integrity sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" @@ -117,6 +153,17 @@ lru-cache "^5.1.1" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz#e30d61abe9480aa5a83232eb31c111be922d2e52" + integrity sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-validator-option" "^7.22.5" + "@nicolo-ribaudo/semver-v6" "^6.3.3" + browserslist "^4.21.9" + lru-cache "^5.1.1" + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c" @@ -275,6 +322,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" @@ -309,6 +363,15 @@ "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.6" + "@babel/types" "^7.22.5" + "@babel/highlight@^7.10.4", "@babel/highlight@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" @@ -323,6 +386,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== +"@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" @@ -532,7 +600,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.22.5": +"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== @@ -1247,6 +1315,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" @@ -1941,6 +2025,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.1.tgz#b48ba7b9c34b51483e6d590f46e5837f1ab5f639" + integrity sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + slash "^3.0.0" + "@jest/core@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" @@ -1975,6 +2071,40 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.1.tgz#fac0d9ddf320490c93356ba201451825231e95f6" + integrity sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/reporters" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.5.0" + jest-config "^29.6.1" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.1" + jest-resolve-dependencies "^29.6.1" + jest-runner "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" + jest-watcher "^29.6.1" + micromatch "^4.0.4" + pretty-format "^29.6.1" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" @@ -1985,6 +2115,16 @@ "@types/node" "*" jest-mock "^27.5.1" +"@jest/environment@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.1.tgz#ee358fff2f68168394b4a50f18c68278a21fe82f" + integrity sha512-RMMXx4ws+Gbvw3DfLSuo2cfQlK7IwGbpuEWXCqyYDcqYTI+9Ju3a5hDnXaxjNsa6uKh9PQF2v+qg+RLe63tz5A== + dependencies: + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.1" + "@jest/expect-utils@^28.1.3": version "28.1.3" resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" @@ -1999,6 +2139,21 @@ dependencies: jest-get-type "^29.4.3" +"@jest/expect-utils@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.1.tgz#ab83b27a15cdd203fe5f68230ea22767d5c3acc5" + integrity sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw== + dependencies: + jest-get-type "^29.4.3" + +"@jest/expect@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.1.tgz#fef18265188f6a97601f1ea0a2912d81a85b4657" + integrity sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg== + dependencies: + expect "^29.6.1" + jest-snapshot "^29.6.1" + "@jest/fake-timers@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" @@ -2011,6 +2166,18 @@ jest-mock "^27.5.1" jest-util "^27.5.1" +"@jest/fake-timers@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.1.tgz#c773efddbc61e1d2efcccac008139f621de57c69" + integrity sha512-RdgHgbXyosCDMVYmj7lLpUwXA4c69vcNzhrt69dJJdf8azUrpRh3ckFCaTPNjsEeRi27Cig0oKDGxy5j7hOgHg== + dependencies: + "@jest/types" "^29.6.1" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" + jest-util "^29.6.1" + "@jest/globals@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" @@ -2020,6 +2187,16 @@ "@jest/types" "^27.5.1" expect "^27.5.1" +"@jest/globals@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.1.tgz#c8a8923e05efd757308082cc22893d82b8aa138f" + integrity sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/types" "^29.6.1" + jest-mock "^29.6.1" + "@jest/reporters@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" @@ -2051,6 +2228,36 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/reporters@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.1.tgz#3325a89c9ead3cf97ad93df3a427549d16179863" + integrity sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + jest-worker "^29.6.1" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + "@jest/schemas@^28.1.3": version "28.1.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" @@ -2065,6 +2272,13 @@ dependencies: "@sinclair/typebox" "^0.25.16" +"@jest/schemas@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" + integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== + dependencies: + "@sinclair/typebox" "^0.27.8" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -2074,6 +2288,15 @@ graceful-fs "^4.2.9" source-map "^0.6.0" +"@jest/source-map@^29.6.0": + version "29.6.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" + integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + "@jest/test-result@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" @@ -2084,6 +2307,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.1.tgz#850e565a3f58ee8ca6ec424db00cb0f2d83c36ba" + integrity sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw== + dependencies: + "@jest/console" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" @@ -2094,6 +2327,16 @@ jest-haste-map "^27.5.1" jest-runtime "^27.5.1" +"@jest/test-sequencer@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.1.tgz#e3e582ee074dd24ea9687d7d1aaf05ee3a9b068e" + integrity sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg== + dependencies: + "@jest/test-result" "^29.6.1" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.1" + slash "^3.0.0" + "@jest/transform@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" @@ -2136,6 +2379,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.1.tgz#acb5606019a197cb99beda3c05404b851f441c92" + integrity sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.1" + jest-regex-util "^29.4.3" + jest-util "^29.6.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -2182,6 +2446,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.6.1": + version "29.6.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" + integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== + dependencies: + "@jest/schemas" "^29.6.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" @@ -2232,7 +2508,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -2639,6 +2915,11 @@ prop-types "^15.8.1" reselect "^4.1.6" +"@nicolo-ribaudo/semver-v6@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" + integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== + "@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" @@ -3372,6 +3653,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@sinonjs/commons@^1.7.0": version "1.8.6" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" @@ -3379,6 +3665,20 @@ dependencies: type-detect "4.0.8" +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + "@sinonjs/fake-timers@^8.0.1": version "8.1.0" resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" @@ -5009,7 +5309,7 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.2": +"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": version "4.1.6" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== @@ -6517,6 +6817,19 @@ babel-jest@^27.5.1: graceful-fs "^4.2.9" slash "^3.0.0" +babel-jest@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.1.tgz#a7141ad1ed5ec50238f3cd36127636823111233a" + integrity sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A== + dependencies: + "@jest/transform" "^29.6.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.5.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" @@ -6568,6 +6881,16 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -6663,6 +6986,14 @@ babel-preset-jest@^27.5.1: babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== + dependencies: + babel-plugin-jest-hoist "^29.5.0" + babel-preset-current-node-syntax "^1.0.0" + bail@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" @@ -6971,7 +7302,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.21.9: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== @@ -7967,6 +8298,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -9129,6 +9465,11 @@ elliptic@^6.5.3, elliptic@^6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -9935,6 +10276,18 @@ expect@^29.0.0: jest-message-util "^29.5.0" jest-util "^29.5.0" +expect@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.1.tgz#64dd1c8f75e2c0b209418f2b8d36a07921adfdf1" + integrity sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g== + dependencies: + "@jest/expect-utils" "^29.6.1" + "@types/node" "*" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + exponential-backoff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" @@ -10085,7 +10438,7 @@ fast-json-parse@^1.0.3: resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -12367,6 +12720,14 @@ jest-changed-files@^27.5.1: execa "^5.0.0" throat "^6.0.1" +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + jest-circus@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" @@ -12392,6 +12753,32 @@ jest-circus@^27.5.1: stack-utils "^2.0.3" throat "^6.0.1" +jest-circus@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.1.tgz#861dab37e71a89907d1c0fabc54a0019738ed824" + integrity sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/expect" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^29.6.1" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-runtime "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" + p-limit "^3.1.0" + pretty-format "^29.6.1" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-cli@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" @@ -12410,6 +12797,24 @@ jest-cli@^27.5.1: prompts "^2.0.1" yargs "^16.2.0" +jest-cli@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.1.tgz#99d9afa7449538221c71f358f0fdd3e9c6e89f72" + integrity sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing== + dependencies: + "@jest/core" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" + prompts "^2.0.1" + yargs "^17.3.1" + jest-config@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" @@ -12440,6 +12845,34 @@ jest-config@^27.5.1: slash "^3.0.0" strip-json-comments "^3.1.1" +jest-config@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.1.tgz#d785344509065d53a238224c6cdc0ed8e2f2f0dd" + integrity sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.6.1" + "@jest/types" "^29.6.1" + babel-jest "^29.6.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.6.1" + jest-environment-node "^29.6.1" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.1" + jest-runner "^29.6.1" + jest-util "^29.6.1" + jest-validate "^29.6.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.6.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-diff@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" @@ -12470,6 +12903,16 @@ jest-diff@^29.5.0: jest-get-type "^29.4.3" pretty-format "^29.5.0" +jest-diff@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.1.tgz#13df6db0a89ee6ad93c747c75c85c70ba941e545" + integrity sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.6.1" + jest-docblock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" @@ -12477,6 +12920,13 @@ jest-docblock@^27.5.1: dependencies: detect-newline "^3.0.0" +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== + dependencies: + detect-newline "^3.0.0" + jest-each@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" @@ -12488,6 +12938,17 @@ jest-each@^27.5.1: jest-util "^27.5.1" pretty-format "^27.5.1" +jest-each@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.1.tgz#975058e5b8f55c6780beab8b6ab214921815c89c" + integrity sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ== + dependencies: + "@jest/types" "^29.6.1" + chalk "^4.0.0" + jest-get-type "^29.4.3" + jest-util "^29.6.1" + pretty-format "^29.6.1" + jest-environment-jsdom@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" @@ -12513,6 +12974,18 @@ jest-environment-node@^27.5.1: jest-mock "^27.5.1" jest-util "^27.5.1" +jest-environment-node@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.1.tgz#08a122dece39e58bc388da815a2166c58b4abec6" + integrity sha512-ZNIfAiE+foBog24W+2caIldl4Irh8Lx1PUhg/GZ0odM1d/h2qORAsejiFc7zb+SEmYPn1yDZzEDSU5PmDkmVLQ== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-mock "^29.6.1" + jest-util "^29.6.1" + jest-get-type@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" @@ -12569,6 +13042,25 @@ jest-haste-map@^27.5.1: optionalDependencies: fsevents "^2.3.2" +jest-haste-map@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.1.tgz#62655c7a1c1b349a3206441330fb2dbdb4b63803" + integrity sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig== + dependencies: + "@jest/types" "^29.6.1" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.4.3" + jest-util "^29.6.1" + jest-worker "^29.6.1" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" @@ -12600,6 +13092,14 @@ jest-leak-detector@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" +jest-leak-detector@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.1.tgz#66a902c81318e66e694df7d096a95466cb962f8e" + integrity sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ== + dependencies: + jest-get-type "^29.4.3" + pretty-format "^29.6.1" + jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" @@ -12630,6 +13130,16 @@ jest-matcher-utils@^29.5.0: jest-get-type "^29.4.3" pretty-format "^29.5.0" +jest-matcher-utils@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz#6c60075d84655d6300c5d5128f46531848160b53" + integrity sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA== + dependencies: + chalk "^4.0.0" + jest-diff "^29.6.1" + jest-get-type "^29.4.3" + pretty-format "^29.6.1" + jest-message-util@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" @@ -12675,6 +13185,21 @@ jest-message-util@^29.5.0: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.1.tgz#d0b21d87f117e1b9e165e24f245befd2ff34ff8d" + integrity sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.6.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.0.6, jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" @@ -12683,6 +13208,15 @@ jest-mock@^27.0.6, jest-mock@^27.5.1: "@jest/types" "^27.5.1" "@types/node" "*" +jest-mock@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.1.tgz#049ee26aea8cbf54c764af649070910607316517" + integrity sha512-brovyV9HBkjXAEdRooaTQK42n8usKoSRR3gihzUpYeV/vwqgSoNfrksO7UfSACnPmxasO/8TmHM3w9Hp3G1dgw== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + jest-util "^29.6.1" + jest-pnp-resolver@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" @@ -12698,6 +13232,11 @@ jest-regex-util@^27.5.1: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== + jest-resolve-dependencies@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" @@ -12707,6 +13246,14 @@ jest-resolve-dependencies@^27.5.1: jest-regex-util "^27.5.1" jest-snapshot "^27.5.1" +jest-resolve-dependencies@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.1.tgz#b85b06670f987a62515bbf625d54a499e3d708f5" + integrity sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw== + dependencies: + jest-regex-util "^29.4.3" + jest-snapshot "^29.6.1" + jest-resolve@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" @@ -12723,6 +13270,21 @@ jest-resolve@^27.5.1: resolve.exports "^1.1.0" slash "^3.0.0" +jest-resolve@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.1.tgz#4c3324b993a85e300add2f8609f51b80ddea39ee" + integrity sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.1" + jest-pnp-resolver "^1.2.2" + jest-util "^29.6.1" + jest-validate "^29.6.1" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + jest-runner@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" @@ -12750,6 +13312,33 @@ jest-runner@^27.5.1: source-map-support "^0.5.6" throat "^6.0.1" +jest-runner@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.1.tgz#54557087e7972d345540d622ab5bfc3d8f34688c" + integrity sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ== + dependencies: + "@jest/console" "^29.6.1" + "@jest/environment" "^29.6.1" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.4.3" + jest-environment-node "^29.6.1" + jest-haste-map "^29.6.1" + jest-leak-detector "^29.6.1" + jest-message-util "^29.6.1" + jest-resolve "^29.6.1" + jest-runtime "^29.6.1" + jest-util "^29.6.1" + jest-watcher "^29.6.1" + jest-worker "^29.6.1" + p-limit "^3.1.0" + source-map-support "0.5.13" + jest-runtime@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" @@ -12778,6 +13367,34 @@ jest-runtime@^27.5.1: slash "^3.0.0" strip-bom "^4.0.0" +jest-runtime@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.1.tgz#8a0fc9274ef277f3d70ba19d238e64334958a0dc" + integrity sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ== + dependencies: + "@jest/environment" "^29.6.1" + "@jest/fake-timers" "^29.6.1" + "@jest/globals" "^29.6.1" + "@jest/source-map" "^29.6.0" + "@jest/test-result" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.6.1" + jest-message-util "^29.6.1" + jest-mock "^29.6.1" + jest-regex-util "^29.4.3" + jest-resolve "^29.6.1" + jest-snapshot "^29.6.1" + jest-util "^29.6.1" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-serializer@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" @@ -12822,6 +13439,33 @@ jest-snapshot@^27.5.1: pretty-format "^27.5.1" semver "^7.3.2" +jest-snapshot@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.1.tgz#0d083cb7de716d5d5cdbe80d598ed2fbafac0239" + integrity sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.6.1" + "@jest/transform" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.6.1" + graceful-fs "^4.2.9" + jest-diff "^29.6.1" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.6.1" + jest-message-util "^29.6.1" + jest-util "^29.6.1" + natural-compare "^1.4.0" + pretty-format "^29.6.1" + semver "^7.5.3" + jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -12858,6 +13502,18 @@ jest-util@^28.1.3: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^29.0.0, jest-util@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.1.tgz#c9e29a87a6edbf1e39e6dee2b4689b8a146679cb" + integrity sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg== + dependencies: + "@jest/types" "^29.6.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-util@^29.5.0: version "29.5.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" @@ -12882,6 +13538,18 @@ jest-validate@^27.5.1: leven "^3.1.0" pretty-format "^27.5.1" +jest-validate@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.1.tgz#765e684af6e2c86dce950aebefbbcd4546d69f7b" + integrity sha512-r3Ds69/0KCN4vx4sYAbGL1EVpZ7MSS0vLmd3gV78O+NAx3PDQQukRU5hNHPXlyqCgFY8XUk7EuTMLugh0KzahA== + dependencies: + "@jest/types" "^29.6.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.4.3" + leven "^3.1.0" + pretty-format "^29.6.1" + jest-watcher@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" @@ -12895,6 +13563,20 @@ jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-watcher@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.1.tgz#7c0c43ddd52418af134c551c92c9ea31e5ec942e" + integrity sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA== + dependencies: + "@jest/test-result" "^29.6.1" + "@jest/types" "^29.6.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.6.1" + string-length "^4.0.1" + jest-worker@^26.5.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -12913,6 +13595,16 @@ jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.1.tgz#64b015f0e985ef3a8ad049b61fe92b3db74a5319" + integrity sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA== + dependencies: + "@types/node" "*" + jest-util "^29.6.1" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@^27.1.0: version "27.5.1" resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" @@ -12922,6 +13614,16 @@ jest@^27.1.0: import-local "^3.0.2" jest-cli "^27.5.1" +jest@^29.5.0: + version "29.6.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.1.tgz#74be1cb719c3abe439f2d94aeb18e6540a5b02ad" + integrity sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw== + dependencies: + "@jest/core" "^29.6.1" + "@jest/types" "^29.6.1" + import-local "^3.0.2" + jest-cli "^29.6.1" + js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -15549,7 +16251,7 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.2: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -16477,6 +17179,15 @@ pretty-format@^29.0.0, pretty-format@^29.5.0: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^29.6.1: + version "29.6.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.1.tgz#ec838c288850b7c4f9090b867c2d4f4edbfb0f3e" + integrity sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog== + dependencies: + "@jest/schemas" "^29.6.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -16715,6 +17426,11 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -17588,6 +18304,11 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.3.2, resolve@^1.9.0: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" @@ -17926,6 +18647,13 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + semver@~7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -18308,6 +19036,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -19282,6 +20018,20 @@ ts-jest@^27.0.5: semver "7.x" yargs-parser "20.x" +ts-jest@^29.1.0: + version "29.1.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + ts-loader@^9.4.2: version "9.4.4" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.4.tgz#6ceaf4d58dcc6979f84125335904920884b7cee4" @@ -19979,7 +20729,7 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" -v8-to-istanbul@^9.0.0: +v8-to-istanbul@^9.0.0, v8-to-istanbul@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== @@ -20129,7 +20879,7 @@ walk-up-path@^1.0.0: resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== -walker@^1.0.7, walker@~1.0.5: +walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== @@ -20619,6 +21369,14 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write-file-atomic@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" @@ -20758,7 +21516,7 @@ yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20. resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@21.1.1, yargs-parser@^21.1.1: +yargs-parser@21.1.1, yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -20786,7 +21544,7 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.6.2: +yargs@^17.3.1, yargs@^17.6.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 4c558db08e5ca6d44e647dfbffedad82d34d0399 Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 18 Jul 2023 17:08:20 +0200 Subject: [PATCH 23/59] add alephium to supported wallets --- nym-connect/desktop/src/pages/menu/Apps.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-connect/desktop/src/pages/menu/Apps.tsx b/nym-connect/desktop/src/pages/menu/Apps.tsx index 5de95cc9c3..dc6584a859 100644 --- a/nym-connect/desktop/src/pages/menu/Apps.tsx +++ b/nym-connect/desktop/src/pages/menu/Apps.tsx @@ -4,7 +4,7 @@ import { Box } from '@mui/system'; const appsSchema = { messagingApps: ['Matrix', 'Telegram', 'Keybase'], - wallets: ['Monero', 'Blockstream', 'Electrum'], + wallets: ['Monero', 'Blockstream', 'Electrum', 'Alephium'], }; export const CompatibleApps = () => ( From 863580a6f2bf2fb19d26733e1a9fe394ae77d79a Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 18 Jul 2023 19:23:31 +0200 Subject: [PATCH 24/59] ci: fix workflow for strapi data publish --- .github/workflows/nym-connect-publish-macos.yml | 2 +- .github/workflows/nym-connect-publish-ubuntu.yml | 2 +- .github/workflows/nym-connect-publish-windows10.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index 21ec00ce1e..bd15cf1554 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index f71c277e0c..70068778f5 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index 8c793d88d0..db152e4e69 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} From fe76ba68a03f848e61e320fb75ae8b4372448923 Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 19 Jul 2023 15:41:00 +0200 Subject: [PATCH 25/59] ci: fix connect-desktop-ci workflow --- .github/workflows/connect-desktop-ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/connect-desktop-ci.yml b/.github/workflows/connect-desktop-ci.yml index 76f39572dc..8fe9a4bbd4 100644 --- a/.github/workflows/connect-desktop-ci.yml +++ b/.github/workflows/connect-desktop-ci.yml @@ -23,7 +23,12 @@ jobs: node-version: 18 - name: Install Yarn run: npm install -g yarn - + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - name: Install project dependencies run: cd ../.. && yarn --network-timeout 100000 From 70e6539298f204f555c683102585790d20db2c3e Mon Sep 17 00:00:00 2001 From: Pierre Dommerc Date: Wed, 19 Jul 2023 15:56:00 +0200 Subject: [PATCH 26/59] refactor(nc-desktop): add privacy level user settings (#3664) --- .../workflows/nym-connect-s-publish-macos.yml | 104 ------------------ .../nym-connect-s-publish-ubuntu.yml | 85 -------------- .../nym-connect-s-publish-windows10.yml | 104 ------------------ nym-connect/desktop/Cargo.lock | 47 ++++++-- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-connect/desktop/src-tauri/src/build.rs | 7 -- .../desktop/src-tauri/src/config/mod.rs | 4 + .../desktop/src-tauri/src/config/user_data.rs | 67 +++++++++++ nym-connect/desktop/src-tauri/src/error.rs | 2 + nym-connect/desktop/src-tauri/src/main.rs | 21 ++-- .../src-tauri/src/operations/common.rs | 29 +++++ .../src/operations/connection/connect.rs | 1 + .../src/operations/connection/status.rs | 7 +- .../src-tauri/src/operations/directory/mod.rs | 32 +++--- nym-connect/desktop/src-tauri/src/state.rs | 36 +++++- nym-connect/desktop/src-tauri/src/tasks.rs | 14 +-- .../src/components/ConnectionStatus.tsx | 6 +- nym-connect/desktop/src/context/main.tsx | 61 +++++----- .../desktop/src/context/mocks/main.tsx | 4 +- nym-connect/desktop/src/hooks/events.ts | 6 +- .../desktop/src/pages/connection/index.tsx | 3 + nym-connect/desktop/src/pages/menu/index.tsx | 3 +- .../menu/settings/MonitoringSettings.tsx | 12 +- .../menu/settings/PrivacyLevelSettings.tsx | 48 ++++++++ nym-connect/desktop/src/routes/index.tsx | 6 +- nym-connect/desktop/src/types/common.ts | 1 - nym-connect/desktop/src/types/index.ts | 2 +- nym-connect/desktop/src/types/user-data.ts | 6 + 28 files changed, 324 insertions(+), 396 deletions(-) delete mode 100644 .github/workflows/nym-connect-s-publish-macos.yml delete mode 100644 .github/workflows/nym-connect-s-publish-ubuntu.yml delete mode 100644 .github/workflows/nym-connect-s-publish-windows10.yml create mode 100644 nym-connect/desktop/src-tauri/src/config/user_data.rs create mode 100644 nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx delete mode 100644 nym-connect/desktop/src/types/common.ts create mode 100644 nym-connect/desktop/src/types/user-data.ts diff --git a/.github/workflows/nym-connect-s-publish-macos.yml b/.github/workflows/nym-connect-s-publish-macos.yml deleted file mode 100644 index d4b50860d6..0000000000 --- a/.github/workflows/nym-connect-s-publish-macos.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: Publish Nym Connect - desktop (MacOS) -on: - workflow_dispatch: - inputs: - release_tag: - required: true - description: Release tag (nym-connect-s-v*) - type: string - default: 'nym-connect-s-v1.0.0' - push: - tags: - - nym-connect-s-v* - -defaults: - run: - working-directory: nym-connect/desktop - -jobs: - publish-tauri: - if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} - strategy: - fail-fast: false - matrix: - platform: [macos-latest] - runs-on: ${{ matrix.platform }} - - steps: - - uses: actions/checkout@v2 - - - name: Node - uses: actions/setup-node@v3 - with: - node-version: 18 - - name: Install Rust stable - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - name: Install the Apple developer certificate for code signing - env: - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - run: | - # create variables - CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 - KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db - - # import certificate and provisioning profile from secrets - echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH - - # create temporary keychain - security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - security set-keychain-settings -lut 21600 $KEYCHAIN_PATH - security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - - # import certificate to keychain - security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH - security list-keychain -d user -s $KEYCHAIN_PATH - - - name: Create env file - uses: timheuer/base64-to-file@v1.2 - with: - fileName: '.env' - encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} - - - name: Prepare for build - env: - RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} - run: ./scripts/pre_medium_build.sh - - - name: Install app dependencies and build it - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} - TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} - TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} - NYM_CONNECT_ENABLE_MEDIUM: 1 - run: yarn && yarn build - - - name: Upload Artifact - uses: actions/upload-artifact@v3 - with: - name: nym-connect-s_1.0.0_x64.dmg - path: nym-connect/desktop/target/release/bundle/dmg/nym-connect-s_1*_x64.dmg - retention-days: 30 - - - name: Clean up keychain - if: ${{ always() }} - run: | - security delete-keychain $RUNNER_TEMP/app-signing.keychain-db - - - id: create-release - name: Upload to release based on tag name - uses: softprops/action-gh-release@v1 - if: github.event_name == 'release' - with: - files: | - nym-connect/desktop/target/release/bundle/dmg/*.dmg - nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz* diff --git a/.github/workflows/nym-connect-s-publish-ubuntu.yml b/.github/workflows/nym-connect-s-publish-ubuntu.yml deleted file mode 100644 index 204a59a87b..0000000000 --- a/.github/workflows/nym-connect-s-publish-ubuntu.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Publish NymConnect S - desktop (Ubuntu) -on: - workflow_dispatch: - inputs: - release_tag: - required: true - description: Release tag (nym-connect-s-v*) - type: string - default: 'nym-connect-s-v1.0.0' - push: - tags: - - nym-connect-s-v* - -defaults: - run: - working-directory: nym-connect/desktop - -jobs: - publish-tauri: - if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} - strategy: - fail-fast: false - matrix: - platform: [custom-runner-linux] - runs-on: ${{ matrix.platform }} - - steps: - - uses: actions/checkout@v2 - - - name: Tauri dependencies - run: > - sudo apt-get update && - sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev - continue-on-error: true - - - name: Node - uses: actions/setup-node@v3 - with: - node-version: 18 - - - name: Install Rust stable - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - - name: Install project dependencies - shell: bash - run: cd .. && yarn --network-timeout 100000 - - - name: Install app dependencies - run: yarn - - - name: Create env file - uses: timheuer/base64-to-file@v1.2 - with: - fileName: '.env' - encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} - - - name: Prepare for build - env: - RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} - run: ./scripts/pre_medium_build.sh - - - name: Build app - run: yarn build - env: - TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} - TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} - NYM_CONNECT_ENABLE_MEDIUM: 1 - - - name: Upload Artifact - uses: actions/upload-artifact@v3 - with: - name: nym-connect-s.AppImage.tar.gz - path: nym-connect/desktop/target/release/bundle/appimage/nym-connect-s_1*_amd64.AppImage - retention-days: 30 - - - id: create-release - name: Upload to release based on tag name - uses: softprops/action-gh-release@v1 - if: github.event_name == 'release' - with: - files: | - nym-connect/desktop/target/release/bundle/appimage/*.AppImage - nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz* diff --git a/.github/workflows/nym-connect-s-publish-windows10.yml b/.github/workflows/nym-connect-s-publish-windows10.yml deleted file mode 100644 index 06d0847b95..0000000000 --- a/.github/workflows/nym-connect-s-publish-windows10.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: Publish Nym Connect - desktop (Windows 10) -on: - workflow_dispatch: - inputs: - release_tag: - required: true - description: Release tag (nym-connect-s-v*) - type: string - default: 'nym-connect-s-v1.0.0' - push: - tags: - - nym-connect-s-v* - -defaults: - run: - working-directory: nym-connect/desktop - -jobs: - publish-tauri: - if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-s-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} - strategy: - fail-fast: false - matrix: - platform: [windows10] - runs-on: ${{ matrix.platform }} - - steps: - - name: Clean up first - continue-on-error: true - working-directory: . - run: | - cd .. - del /s /q /A:H nym - rmdir /s /q nym - - - uses: actions/checkout@v3 - - - name: Import signing certificate - env: - WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} - WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} - run: | - New-Item -ItemType directory -Path certificate - Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE - certutil -decode certificate/tempCert.txt certificate/certificate.pfx - Remove-Item -path certificate -include tempCert.txt - Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText) - - - name: Node - uses: actions/setup-node@v3 - with: - node-version: 18 - - - name: Install Rust stable - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - - name: Create env file - uses: timheuer/base64-to-file@v1.2 - with: - fileName: '.env' - encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} - - - name: Install project dependencies - shell: bash - run: cd .. && yarn --network-timeout 100000 - - - name: Install app dependencies - shell: bash - run: yarn --network-timeout 100000 - - - name: Prepare for build - env: - RELEASE_TAG: ${{ github.ref_name || inputs.release_tag }} - run: ./scripts/pre_medium_build.sh - - - name: Build and sign it - shell: bash - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }} - WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} - WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} - TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} - TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} - NYM_CONNECT_ENABLE_MEDIUM: 1 - run: yarn build - - - name: Upload Artifact - uses: actions/upload-artifact@v3 - with: - name: nym-connect-s_1.0.0_x64_en-US.msi - path: nym-connect/desktop/target/release/bundle/msi/nym-connect-s_1*_x64_en-US.msi - retention-days: 30 - - - id: create-release - name: Upload to release based on tag name - uses: softprops/action-gh-release@v1 - if: github.event_name == 'release' - with: - files: | - nym-connect/desktop/target/release/bundle/msi/*.msi - nym-connect/desktop/target/release/bundle/msi/*.msi.zip* diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 4b515a4f54..a5c4fe58a1 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1532,6 +1532,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "errno" version = "0.2.8" @@ -2217,7 +2223,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.2", "slab", "tokio", "tokio-util", @@ -2256,6 +2262,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "hashlink" version = "0.7.0" @@ -2618,6 +2630,16 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "infer" version = "0.7.0" @@ -3462,6 +3484,7 @@ dependencies = [ "thiserror", "time", "tokio", + "toml 0.7.4", "ts-rs", "url", "yaml-rust", @@ -4530,7 +4553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bd9647b268a3d3e14ff09c23201133a62589c658db02bb7388c7246aafe0590" dependencies = [ "base64 0.21.2", - "indexmap", + "indexmap 1.9.2", "line-wrap", "quick-xml 0.28.1", "serde", @@ -5129,7 +5152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" dependencies = [ "dyn-clone", - "indexmap", + "indexmap 1.9.2", "schemars_derive", "serde", "serde_json", @@ -5345,9 +5368,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -5677,7 +5700,7 @@ dependencies = [ "futures-util", "hashlink 0.7.0", "hex", - "indexmap", + "indexmap 1.9.2", "itoa 1.0.6", "libc", "libsqlite3-sys", @@ -5723,7 +5746,7 @@ dependencies = [ "futures-util", "hashlink 0.8.1", "hex", - "indexmap", + "indexmap 1.9.2", "itoa 1.0.6", "libc", "libsqlite3-sys", @@ -6580,20 +6603,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index ffd4c43461..fb4b06a1df 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -43,7 +43,7 @@ time = { version = "0.3.17", features = ["local-offset"] } tokio = { version = "1.24.1", features = ["sync", "time"] } url = "2.2" yaml-rust = "0.4" - +toml = "0.7" nym-client-core = { path = "../../../common/client-core" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } diff --git a/nym-connect/desktop/src-tauri/src/build.rs b/nym-connect/desktop/src-tauri/src/build.rs index 2c8232a54b..261851f6b6 100644 --- a/nym-connect/desktop/src-tauri/src/build.rs +++ b/nym-connect/desktop/src-tauri/src/build.rs @@ -1,10 +1,3 @@ -use std::env; - fn main() { - if env::var_os("NYM_CONNECT_ENABLE_MEDIUM").is_some() { - println!("cargo:rustc-cfg=medium_enabled"); - } - println!("cargo:rerun-if-changed=build.rs"); - tauri_build::build(); } diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 3c76500aab..f2cbff0d46 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -26,6 +26,10 @@ mod old_config_v1_1_20_2; mod persistence; mod template; mod upgrade; +mod user_data; + +pub use user_data::PrivacyLevel; +pub use user_data::UserData; static SOCKS5_CONFIG_ID: &str = "nym-connect"; diff --git a/nym-connect/desktop/src-tauri/src/config/user_data.rs b/nym-connect/desktop/src-tauri/src/config/user_data.rs new file mode 100644 index 0000000000..3e9287f375 --- /dev/null +++ b/nym-connect/desktop/src-tauri/src/config/user_data.rs @@ -0,0 +1,67 @@ +use eyre::{eyre, Context, Result}; +use log::error; +use serde::{Deserialize, Serialize}; +use std::{fs, str}; +use tauri::api::path::data_dir; + +const DATA_DIR: &str = "nym-connect"; +const DATA_FILE: &str = "user-data.toml"; + +#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)] +pub enum PrivacyLevel { + #[default] + High, + Medium, +} + +// User data is read from and write on disk +// Linux: $XDG_DATA_HOME or $HOME/.local/share/ +// macOS: $HOME/Library/Application Support +// Windows: {FOLDERID_RoamingAppData} +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct UserData { + pub monitoring: Option, + pub privacy_level: Option, +} + +fn create_directory_path() -> Result<()> { + let mut data_dir = data_dir().ok_or(eyre!("Failed to retrieve data directory"))?; + data_dir.push(DATA_DIR); + + fs::create_dir_all(&data_dir).context(format!( + "Failed to create user data directory path {}", + data_dir.display() + )) +} + +impl UserData { + pub fn read() -> Result { + // create the full directory path if it is missing + create_directory_path()?; + + let mut data_path = data_dir().ok_or(eyre!("Failed to retrieve data directory"))?; + + data_path.push(DATA_DIR); + data_path.push(DATA_FILE); + let content = fs::read(&data_path) + .context(format!("Failed to read user data {}", data_path.display()))?; + + toml::from_str::(str::from_utf8(&content)?).map_err(|e| { + error!("{}", e); + eyre!("{e}") + }) + } + + pub fn write(&self) -> Result<()> { + // create the full directory path if it is missing + create_directory_path()?; + + let mut data_path = data_dir().ok_or(eyre!("Failed to retrieve data directory"))?; + + data_path.push(DATA_DIR); + data_path.push(DATA_FILE); + let toml = toml::to_string(&self)?; + fs::write(data_path, toml)?; + Ok(()) + } +} diff --git a/nym-connect/desktop/src-tauri/src/error.rs b/nym-connect/desktop/src-tauri/src/error.rs index 0540f01daf..651e741aea 100644 --- a/nym-connect/desktop/src-tauri/src/error.rs +++ b/nym-connect/desktop/src-tauri/src/error.rs @@ -70,6 +70,8 @@ pub enum BackendError { NewWindowError, #[error("unable to parse the specified gateway")] UnableToParseGateway, + #[error("unable to write user data to disk")] + UserDataWriteError, #[error("unable to load keys: {source}")] UnableToLoadKeys { diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index f41f401812..8a926938d1 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -9,8 +9,9 @@ use nym_config::defaults::setup_env; use tauri::Manager; use tokio::sync::RwLock; +use crate::config::UserData; use crate::menu::{create_tray_menu, tray_menu_event_handler}; -use crate::state::{is_medium_enabled, State}; +use crate::state::State; use crate::window::window_toggle; mod config; @@ -25,12 +26,6 @@ mod tasks; mod window; fn main() { - if is_medium_enabled() { - println!("medium mode enabled"); - std::env::set_var("NYM_CONNECT_DISABLE_COVER", "1"); - std::env::set_var("NYM_CONNECT_ENABLE_MIXED_SIZE_PACKETS", "1"); - std::env::set_var("NYM_CONNECT_DISABLE_PER_HOP_DELAYS", "1"); - } setup_env(None); println!("Starting up..."); @@ -40,13 +35,22 @@ fn main() { log::warn!("Failed to fix PATH: {error}"); } + let user_data = UserData::read().unwrap_or_else(|e| { + println!("{}", e); + println!("Fallback to default"); + UserData::default() + }); + let context = tauri::generate_context!(); tauri::Builder::default() - .manage(Arc::new(RwLock::new(State::new()))) + .manage(Arc::new(RwLock::new(State::new(user_data)))) .invoke_handler(tauri::generate_handler![ crate::operations::config::get_config_file_location, crate::operations::config::get_config_id, crate::operations::common::get_env, + crate::operations::common::get_user_data, + crate::operations::common::set_monitoring, + crate::operations::common::set_privacy_level, crate::operations::connection::connect::get_gateway, crate::operations::connection::connect::get_service_provider, crate::operations::connection::connect::set_gateway, @@ -57,7 +61,6 @@ fn main() { crate::operations::connection::status::get_connection_status, crate::operations::connection::status::get_gateway_connection_status, crate::operations::connection::status::start_connection_health_check_task, - crate::operations::connection::status::is_medium_mode_enabled, crate::operations::directory::get_services, crate::operations::directory::get_gateways_detailed, crate::operations::export::export_keys, diff --git a/nym-connect/desktop/src-tauri/src/operations/common.rs b/nym-connect/desktop/src-tauri/src/operations/common.rs index 707dd19860..a4e9604d60 100644 --- a/nym-connect/desktop/src-tauri/src/operations/common.rs +++ b/nym-connect/desktop/src-tauri/src/operations/common.rs @@ -1,4 +1,9 @@ +use crate::config::PrivacyLevel; +use crate::error::Result; +use crate::{config::UserData, state::State}; use std::env; +use std::sync::Arc; +use tokio::sync::RwLock; #[tauri::command] pub async fn get_env(variable: String) -> Option { @@ -7,3 +12,27 @@ pub async fn get_env(variable: String) -> Option { var } + +#[tauri::command] +pub async fn get_user_data(state: tauri::State<'_, Arc>>) -> Result { + let guard = state.read().await; + Ok(guard.get_user_data().clone()) +} + +#[tauri::command] +pub async fn set_monitoring( + enabled: bool, + state: tauri::State<'_, Arc>>, +) -> Result<()> { + let mut guard = state.write().await; + guard.set_monitoring(enabled) +} + +#[tauri::command] +pub async fn set_privacy_level( + privacy_level: PrivacyLevel, + state: tauri::State<'_, Arc>>, +) -> Result<()> { + let mut guard = state.write().await; + guard.set_privacy_level(privacy_level) +} diff --git a/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs b/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs index 1d83748698..95a125fa30 100644 --- a/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs +++ b/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs @@ -12,6 +12,7 @@ pub async fn start_connecting( window: tauri::Window, ) -> Result { log::trace!("Start connecting"); + let (msg_receiver, exit_status_receiver) = { let mut state_w = state.write().await; state_w.start_connecting(&window).await? diff --git a/nym-connect/desktop/src-tauri/src/operations/connection/status.rs b/nym-connect/desktop/src-tauri/src/operations/connection/status.rs index 8391f724cf..7710524fb5 100644 --- a/nym-connect/desktop/src-tauri/src/operations/connection/status.rs +++ b/nym-connect/desktop/src-tauri/src/operations/connection/status.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use tokio::sync::RwLock; use crate::models::{ConnectionStatusKind, ConnectivityTestResult, GatewayConnectionStatusKind}; -use crate::state::{is_medium_enabled, State}; +use crate::state::State; #[tauri::command] pub async fn get_connection_status( @@ -42,8 +42,3 @@ pub fn start_connection_health_check_task( ) { tasks::start_connection_check(state.inner().clone(), window); } - -#[tauri::command] -pub async fn is_medium_mode_enabled(_state: tauri::State<'_, Arc>>) -> Result { - Ok(is_medium_enabled()) -} diff --git a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs index 77bd2b8e84..0b1d36819f 100644 --- a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs +++ b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs @@ -1,12 +1,15 @@ use itertools::Itertools; +use crate::config::PrivacyLevel; use crate::error::Result; use crate::models::{ DirectoryService, DirectoryServiceProvider, HarbourMasterService, PagedResult, }; -use crate::state::is_medium_enabled; +use crate::state::State; use nym_api_requests::models::GatewayBondAnnotated; use nym_contracts_common::types::Percent; +use std::sync::Arc; +use tokio::sync::RwLock; static SERVICE_PROVIDER_WELLKNOWN_URL: &str = "https://nymtech.net/.wellknown/connect/service-providers.json"; @@ -20,21 +23,20 @@ static HARBOUR_MASTER_URL: &str = "https://harbourmaster.nymtech.net/v1/services static GATEWAYS_DETAILED_URL: &str = "https://validator.nymtech.net/api/v1/status/gateways/detailed"; -fn get_services_url() -> &'static str { - if is_medium_enabled() { - return SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM; - } - SERVICE_PROVIDER_WELLKNOWN_URL -} - #[tauri::command] -pub async fn get_services() -> Result> { +pub async fn get_services( + state: tauri::State<'_, Arc>>, +) -> Result> { log::trace!("Fetching services"); - let all_services = fetch_services().await?; + + let guard = state.read().await; + let privacy_level = guard.get_user_data().privacy_level.unwrap_or_default(); + + let all_services = fetch_services(&privacy_level).await?; log::trace!("Received: {:#?}", all_services); // Early return if we're running with medium toggle enabled - if is_medium_enabled() { + if let PrivacyLevel::Medium = privacy_level { return Ok(all_services.into_iter().flat_map(|sp| sp.items).collect()); } @@ -100,8 +102,12 @@ fn filter_out_poor_gateways( .collect() } -async fn fetch_services() -> Result> { - let services_url = get_services_url(); +async fn fetch_services(privacy_level: &PrivacyLevel) -> Result> { + let services_url = match privacy_level { + PrivacyLevel::Medium => SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM, + _ => SERVICE_PROVIDER_WELLKNOWN_URL, + }; + let services_res = reqwest::get(services_url) .await? .json::>() diff --git a/nym-connect/desktop/src-tauri/src/state.rs b/nym-connect/desktop/src-tauri/src/state.rs index b44ca16107..044b185b86 100644 --- a/nym-connect/desktop/src-tauri/src/state.rs +++ b/nym-connect/desktop/src-tauri/src/state.rs @@ -1,4 +1,5 @@ use futures::SinkExt; +use log::error; use nym_client_core::error::ClientCoreStatusMessage; use nym_socks5_client_core::{Socks5ControlMessage, Socks5ControlMessageSender}; use std::time::Duration; @@ -7,6 +8,8 @@ use tauri::Manager; use tokio::time::Instant; use crate::config::Config; +use crate::config::PrivacyLevel; +use crate::config::UserData; use crate::{ config::{self, socks5_config_id_appended_with}, error::{BackendError, Result}, @@ -65,10 +68,13 @@ pub struct State { /// The latest end-to-end connectivity test result. The first test is initiated on connection /// established. Additional tests can be triggered. connectivity_test_result: ConnectivityTestResult, + + /// User data saved on disk, like user settings + user_data: UserData, } impl State { - pub fn new() -> Self { + pub fn new(user_data: UserData) -> Self { State { status: ConnectionStatusKind::Disconnected, service_provider: None, @@ -76,6 +82,7 @@ impl State { socks5_client_sender: None, gateway_connectivity: GatewayConnectivity::Good, connectivity_test_result: ConnectivityTestResult::NotAvailable, + user_data, } } @@ -93,6 +100,26 @@ impl State { self.gateway_connectivity } + pub fn get_user_data(&self) -> &UserData { + &self.user_data + } + + pub fn set_monitoring(&mut self, enabled: bool) -> Result<()> { + self.user_data.monitoring = Some(enabled); + self.user_data.write().map_err(|e| { + error!("Failed to write user data to disk {e}"); + BackendError::UserDataWriteError + }) + } + + pub fn set_privacy_level(&mut self, privacy_level: PrivacyLevel) -> Result<()> { + self.user_data.privacy_level = Some(privacy_level); + self.user_data.write().map_err(|e| { + error!("Failed to write user data to disk {e}"); + BackendError::UserDataWriteError + }) + } + pub fn set_gateway_connectivity(&mut self, gateway_connectivity: GatewayConnectivity) { self.gateway_connectivity = gateway_connectivity } @@ -200,8 +227,9 @@ impl State { &mut self, ) -> Result<(nym_task::StatusReceiver, ExitStatusReceiver)> { let id = self.get_config_id()?; + let privacy_level = self.user_data.privacy_level.unwrap_or_default(); let (control_tx, msg_rx, exit_status_rx, used_gateway) = - tasks::start_nym_socks5_client(&id).await?; + tasks::start_nym_socks5_client(&id, &privacy_level).await?; self.socks5_client_sender = Some(control_tx); self.gateway = Some(used_gateway.gateway_id); Ok((msg_rx, exit_status_rx)) @@ -244,7 +272,3 @@ impl State { self.set_state(ConnectionStatusKind::Disconnected, window); } } - -pub fn is_medium_enabled() -> bool { - cfg!(medium_enabled) || std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() -} diff --git a/nym-connect/desktop/src-tauri/src/tasks.rs b/nym-connect/desktop/src-tauri/src/tasks.rs index d6ac1b0918..8c69b1be7e 100644 --- a/nym-connect/desktop/src-tauri/src/tasks.rs +++ b/nym-connect/desktop/src-tauri/src/tasks.rs @@ -10,7 +10,7 @@ use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; -use crate::config::Config; +use crate::config::{Config, PrivacyLevel}; use crate::{ error::Result, events::{self, emit_event, emit_status_event}, @@ -30,23 +30,20 @@ pub enum Socks5ExitStatusMessage { Failed(Box), } -fn override_config_from_env(config: &mut Config) { +fn override_config_from_env(config: &mut Config, privacy_level: &PrivacyLevel) { // Disable both the loop cover traffic that runs in the background as well as the Poisson // process that injects cover traffic into the traffic stream. - if std::env::var("NYM_CONNECT_DISABLE_COVER").is_ok() { + if let PrivacyLevel::Medium = privacy_level { + log::info!("Running in Medium privacy level"); log::warn!("Disabling cover traffic"); config.core.base.set_no_cover_traffic_with_keepalive(); - } - if std::env::var("NYM_CONNECT_ENABLE_MIXED_SIZE_PACKETS").is_ok() { log::warn!("Enabling mixed size packets"); config .core .base .set_secondary_packet_size(Some(PacketSize::ExtendedPacket16)); - } - if std::env::var("NYM_CONNECT_DISABLE_PER_HOP_DELAYS").is_ok() { log::warn!("Disabling per-hop delay"); config.core.base.set_no_per_hop_delays(); } @@ -55,6 +52,7 @@ fn override_config_from_env(config: &mut Config) { /// The main SOCKS5 client task. It loads the configuration from file determined by the `id`. pub async fn start_nym_socks5_client( id: &str, + privacy_level: &PrivacyLevel, ) -> Result<( Socks5ControlMessageSender, nym_task::StatusReceiver, @@ -65,7 +63,7 @@ pub async fn start_nym_socks5_client( let mut config = Config::read_from_default_path(id) .tap_err(|_| log::warn!("Failed to load configuration file"))?; - override_config_from_env(&mut config); + override_config_from_env(&mut config, privacy_level); log::trace!("Configuration used: {:#?}", config); diff --git a/nym-connect/desktop/src/components/ConnectionStatus.tsx b/nym-connect/desktop/src/components/ConnectionStatus.tsx index c23abdb7d8..73fb6bf992 100644 --- a/nym-connect/desktop/src/components/ConnectionStatus.tsx +++ b/nym-connect/desktop/src/components/ConnectionStatus.tsx @@ -16,7 +16,7 @@ const ConnectionStatusContent: FCWithChildren<{ serviceProvider?: ServiceProvider; gatewayError: boolean; }> = ({ status, serviceProvider, gatewayError }) => { - const { speedMode } = useClientContext(); + const { userData } = useClientContext(); if (gatewayError) { return ( @@ -49,10 +49,10 @@ const ConnectionStatusContent: FCWithChildren<{ - {speedMode === 'medium' && ( + {userData?.privacy_level === 'Medium' && ( - Speedy mode activated + Speed boost activated )} diff --git a/nym-connect/desktop/src/context/main.tsx b/nym-connect/desktop/src/context/main.tsx index 462c425800..f51e73389d 100644 --- a/nym-connect/desktop/src/context/main.tsx +++ b/nym-connect/desktop/src/context/main.tsx @@ -3,23 +3,24 @@ import { DateTime } from 'luxon'; import { invoke } from '@tauri-apps/api'; import { Error } from 'src/types/error'; import { getVersion } from '@tauri-apps/api/app'; +import * as Sentry from '@sentry/react'; import { useEvents } from 'src/hooks/events'; import { UserDefinedGateway, UserDefinedSPAddress } from 'src/types/service-provider'; import { getItemFromStorage, setItemInStorage } from 'src/utils'; -import { ConnectionStatusKind, GatewayPerformance, SpeedMode } from '../types'; +import { ConnectionStatusKind, GatewayPerformance, PrivacyLevel, UserData } from '../types'; import { ConnectionStatsItem } from '../components/ConnectionStats'; import { ServiceProvider } from '../types/directory'; import initSentry from '../sentry'; const FORAGE_GATEWAY_KEY = 'nym-connect-user-gateway'; const FORAGE_SP_KEY = 'nym-connect-user-sp'; -const FORAGE_MONITORING_ENABLED = 'nym-connect-monitoring-enabled'; type ModeType = 'light' | 'dark'; export type TClientContext = { mode: ModeType; appVersion?: string; + userData?: UserData; connectionStatus: ConnectionStatusKind; connectionStats?: ConnectionStatsItem[]; connectedSince?: DateTime; @@ -32,7 +33,6 @@ export type TClientContext = { serviceProviders?: ServiceProvider[]; setMode: (mode: ModeType) => void; clearError: () => void; - monitoringEnabled: boolean; setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void; setConnectionStats: (connectionStats: ConnectionStatsItem[] | undefined) => void; setConnectedSince: (connectedSince: DateTime | undefined) => void; @@ -43,7 +43,7 @@ export type TClientContext = { setUserDefinedGateway: React.Dispatch>; setUserDefinedSPAddress: React.Dispatch>; setMonitoring: (value: boolean) => Promise; - speedMode: SpeedMode; + setPrivacyLevel: (value: PrivacyLevel) => Promise; }; export const ClientContext = createContext({} as TClientContext); @@ -67,19 +67,26 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { isActive: false, address: undefined, }); - const [monitoringEnabled, setMonitoringEnabled] = useState(false); - const [speedMode, setspeedMode] = useState('slow'); + const [userData, setUserData] = useState(); const getAppVersion = async () => { const version = await getVersion(); return version; }; + const getUserData = async () => { + const data = await invoke('get_user_data'); + if (!data.privacy_level) { + data.privacy_level = 'High'; + } + setUserData(data); + return data; + }; + useEffect(() => { const initSentryClient = async () => { - const monitoring = await getItemFromStorage({ key: FORAGE_MONITORING_ENABLED }); - setMonitoringEnabled(Boolean(monitoring)); - if (monitoring === true) { + const data = await getUserData(); + if (data.monitoring) { await initSentry(); } }; @@ -87,17 +94,6 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { initSentryClient(); }, []); - useEffect(() => { - const initSpeedMode = async () => { - const isEnabled = await invoke('is_medium_mode_enabled'); - if (isEnabled) { - setspeedMode('medium'); - } - }; - - initSpeedMode(); - }, []); - useEffect(() => { setItemInStorage({ key: FORAGE_GATEWAY_KEY, value: userDefinedGateway }); }, [userDefinedGateway]); @@ -124,7 +120,10 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { }; useEvents({ - onError: (e) => setError(e), + onError: (e) => { + setError(e); + Sentry.captureException(e); + }, onGatewayPerformanceChange: (performance) => setGatewayPerformance(performance), onStatusChange: (status) => setConnectionStatus(status), }); @@ -147,6 +146,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { } catch (e) { setError({ title: 'Could not connect', message: e as string }); console.log(e); + Sentry.captureException(e); } }, []); @@ -155,6 +155,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { await invoke('start_disconnecting'); } catch (e) { console.log(e); + Sentry.captureException(e); } }, []); @@ -197,8 +198,15 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { const clearError = () => setError(undefined); const setMonitoring = async (value: boolean) => { - setMonitoringEnabled(value); - await setItemInStorage({ key: FORAGE_MONITORING_ENABLED, value }); + await invoke('set_monitoring', { enabled: value }); + // refresh user data + await getUserData(); + }; + + const setPrivacyLevel = async (value: PrivacyLevel) => { + await invoke('set_privacy_level', { privacyLevel: value }); + // refresh user data + await getUserData(); }; const contextValue = useMemo( @@ -216,7 +224,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { selectedProvider, serviceProviders, connectedSince, - monitoringEnabled, + userData, setConnectedSince, setSerivceProvider, startConnecting, @@ -228,7 +236,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { setUserDefinedGateway, setUserDefinedSPAddress, setMonitoring, - speedMode, + setPrivacyLevel, }), [ mode, @@ -244,8 +252,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { selectedProvider, userDefinedGateway, userDefinedSPAddress, - monitoringEnabled, - speedMode, + userData, ], ); diff --git a/nym-connect/desktop/src/context/mocks/main.tsx b/nym-connect/desktop/src/context/mocks/main.tsx index 9ae5495ac8..8fdd8518c9 100644 --- a/nym-connect/desktop/src/context/mocks/main.tsx +++ b/nym-connect/desktop/src/context/mocks/main.tsx @@ -11,8 +11,7 @@ const mockValues: TClientContext = { showInfoModal: false, userDefinedGateway: { isActive: false, gateway: '' }, userDefinedSPAddress: { isActive: false, address: '' }, - monitoringEnabled: false, - speedMode: 'slow', + userData: { monitoring: false, privacy_level: 'High' }, setShowInfoModal: () => {}, setMode: () => {}, clearError: () => {}, @@ -25,6 +24,7 @@ const mockValues: TClientContext = { setUserDefinedGateway: () => {}, setUserDefinedSPAddress: () => {}, setMonitoring: async () => {}, + setPrivacyLevel: async () => {}, }; export const MockProvider: FCWithChildren<{ diff --git a/nym-connect/desktop/src/hooks/events.ts b/nym-connect/desktop/src/hooks/events.ts index 4b2c4fcc55..0b15e5347d 100644 --- a/nym-connect/desktop/src/hooks/events.ts +++ b/nym-connect/desktop/src/hooks/events.ts @@ -1,5 +1,6 @@ import { useEffect, useRef } from 'react'; import { listen, UnlistenFn } from '@tauri-apps/api/event'; +import * as Sentry from '@sentry/react'; import { ConnectionStatusKind, GatewayPerformance } from 'src/types'; import { Error } from 'src/types/error'; import { TauriEvent } from 'src/types/event'; @@ -29,7 +30,10 @@ export const useEvents = ({ .then((result) => { unlisten.push(result); }) - .catch((e) => console.log(e)); + .catch((e) => { + console.log(e); + Sentry.captureException(e); + }); listen('socks5-event', (e: TauriEvent) => { console.log(e); diff --git a/nym-connect/desktop/src/pages/connection/index.tsx b/nym-connect/desktop/src/pages/connection/index.tsx index 2ba081331f..bbdf0a6125 100644 --- a/nym-connect/desktop/src/pages/connection/index.tsx +++ b/nym-connect/desktop/src/pages/connection/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { forage } from '@tauri-apps/tauri-forage'; +import * as Sentry from '@sentry/react'; import { DateTime } from 'luxon'; import { useClientContext } from 'src/context/main'; import { useTauriEvents } from 'src/utils'; @@ -28,12 +29,14 @@ export const ConnectionPage = () => { // eslint-disable-next-line default-case switch (currentStatus) { case 'disconnected': + Sentry.captureMessage('start connect', 'info'); await context.setSerivceProvider(); await context.startConnecting(); context.setConnectedSince(DateTime.now()); context.setShowInfoModal(true); break; case 'connected': + Sentry.captureMessage('start disconnect', 'info'); await context.startDisconnecting(); context.setConnectedSince(undefined); break; diff --git a/nym-connect/desktop/src/pages/menu/index.tsx b/nym-connect/desktop/src/pages/menu/index.tsx index da4f2be73d..67576dc88c 100644 --- a/nym-connect/desktop/src/pages/menu/index.tsx +++ b/nym-connect/desktop/src/pages/menu/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Apps, HelpOutline, Settings, BugReport } from '@mui/icons-material'; +import { Apps, HelpOutline, Settings, BugReport, PrivacyTip } from '@mui/icons-material'; import { Stack, Link, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; import { Link as RouterLink } from 'react-router-dom'; import { AppVersion } from 'src/components/AppVersion'; @@ -7,6 +7,7 @@ import { AppVersion } from 'src/components/AppVersion'; const menuSchema = [ { title: 'Supported apps', icon: Apps, path: 'apps' }, { title: 'How to connect guide', icon: HelpOutline, path: 'guide' }, + { title: 'Privacy level', icon: PrivacyTip, path: 'privacy-level' }, { title: 'Please help us improve the app', icon: BugReport, path: 'monitoring' }, { title: 'Settings', icon: Settings, path: 'settings' }, ]; diff --git a/nym-connect/desktop/src/pages/menu/settings/MonitoringSettings.tsx b/nym-connect/desktop/src/pages/menu/settings/MonitoringSettings.tsx index 92e15a155d..8b899cbe72 100644 --- a/nym-connect/desktop/src/pages/menu/settings/MonitoringSettings.tsx +++ b/nym-connect/desktop/src/pages/menu/settings/MonitoringSettings.tsx @@ -4,8 +4,8 @@ import { Box, FormControl, FormControlLabel, FormHelperText, Stack, Switch, Typo import { useClientContext } from 'src/context/main'; export const MonitoringSettings = () => { - const { monitoringEnabled, setMonitoring } = useClientContext(); - const [enabled, setEnabled] = useState(monitoringEnabled); + const { userData, setMonitoring } = useClientContext(); + const [enabled, setEnabled] = useState(userData?.monitoring || false); const [loading, setLoading] = useState(false); const handleChange = async (e: ChangeEvent) => { @@ -25,7 +25,13 @@ export const MonitoringSettings = () => { + } label="Enable" /> diff --git a/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx new file mode 100644 index 0000000000..5c2241b4d0 --- /dev/null +++ b/nym-connect/desktop/src/pages/menu/settings/PrivacyLevelSettings.tsx @@ -0,0 +1,48 @@ +import React, { ChangeEvent, useState } from 'react'; +import * as Sentry from '@sentry/react'; +import { Box, FormControl, FormControlLabel, FormHelperText, Stack, Switch, Typography } from '@mui/material'; +import { useClientContext } from 'src/context/main'; + +export const PrivacyLevelSettings = () => { + const { userData, setPrivacyLevel } = useClientContext(); + const [speedBoost, setSpeedBoost] = useState(userData?.privacy_level !== 'High'); + const [loading, setLoading] = useState(false); + + const handleChange = async (e: ChangeEvent) => { + setLoading(true); + setSpeedBoost(e.target.checked); + Sentry.captureMessage(`privacy level switched to ${e.target.checked ? 'Medium' : 'High'}`, 'info'); + await setPrivacyLevel(e.target.checked ? 'Medium' : 'High'); + setLoading(false); + }; + + return ( + + + + + Speed boost + + + + } + label="Enable" + /> + + By activating this option, the connection speed will be relatively faster in exchange of relaxing some + protections + + + + + + ); +}; diff --git a/nym-connect/desktop/src/routes/index.tsx b/nym-connect/desktop/src/routes/index.tsx index 8af5a703e3..f1e4b1da67 100644 --- a/nym-connect/desktop/src/routes/index.tsx +++ b/nym-connect/desktop/src/routes/index.tsx @@ -9,14 +9,15 @@ import { SettingsMenu } from 'src/pages/menu/settings'; import { GatewaySettings } from 'src/pages/menu/settings/GatewaySettings'; import { ServiceProviderSettings } from 'src/pages/menu/settings/ServiceProviderSettings'; import { MonitoringSettings } from '../pages/menu/settings/MonitoringSettings'; +import { PrivacyLevelSettings } from '../pages/menu/settings/PrivacyLevelSettings'; import { useClientContext } from '../context/main'; const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes); export const AppRoutes = () => { - const { monitoringEnabled } = useClientContext(); + const { userData } = useClientContext(); - const RoutesContainer = monitoringEnabled ? SentryRoutes : Routes; + const RoutesContainer = userData?.monitoring ? SentryRoutes : Routes; return ( @@ -25,6 +26,7 @@ export const AppRoutes = () => { } /> } /> } /> + } /> } /> } /> diff --git a/nym-connect/desktop/src/types/common.ts b/nym-connect/desktop/src/types/common.ts deleted file mode 100644 index d4895499d5..0000000000 --- a/nym-connect/desktop/src/types/common.ts +++ /dev/null @@ -1 +0,0 @@ -export type SpeedMode = 'fast' | 'medium' | 'slow'; diff --git a/nym-connect/desktop/src/types/index.ts b/nym-connect/desktop/src/types/index.ts index f8ea4fd95f..7ebac88588 100644 --- a/nym-connect/desktop/src/types/index.ts +++ b/nym-connect/desktop/src/types/index.ts @@ -1,3 +1,3 @@ export * from './rust'; export * from './connection'; -export * from './common'; +export * from './user-data'; diff --git a/nym-connect/desktop/src/types/user-data.ts b/nym-connect/desktop/src/types/user-data.ts new file mode 100644 index 0000000000..8bd43a941e --- /dev/null +++ b/nym-connect/desktop/src/types/user-data.ts @@ -0,0 +1,6 @@ +export type PrivacyLevel = 'High' | 'Medium'; + +export type UserData = { + monitoring?: boolean; + privacy_level?: PrivacyLevel; +}; From 415fe4605c133133625f71ac1a2184aba3f448b3 Mon Sep 17 00:00:00 2001 From: Pierre Dommerc Date: Thu, 20 Jul 2023 13:17:49 +0200 Subject: [PATCH 27/59] feat(nc-desktop): add sentry to backend (#3652) --- nym-connect/desktop/Cargo.lock | 266 ++++++++++++++++++- nym-connect/desktop/src-tauri/Cargo.toml | 2 + nym-connect/desktop/src-tauri/src/logging.rs | 22 +- nym-connect/desktop/src-tauri/src/main.rs | 41 ++- 4 files changed, 326 insertions(+), 5 deletions(-) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index a5c4fe58a1..18ef59a2d7 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -8,6 +8,15 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -88,6 +97,9 @@ name = "anyhow" version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +dependencies = [ + "backtrace", +] [[package]] name = "arrayref" @@ -193,6 +205,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.7.1", + "object", + "rustc-demangle", +] + [[package]] name = "base16ct" version = "0.1.1" @@ -1238,6 +1265,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid 1.3.0", +] + [[package]] name = "der" version = "0.6.1" @@ -1646,6 +1683,18 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + [[package]] name = "fix-path-env" version = "0.1.0" @@ -1662,7 +1711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -1991,6 +2040,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "gio" version = "0.15.12" @@ -2403,6 +2458,17 @@ dependencies = [ "digest 0.10.6", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -3047,6 +3113,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.1.0" @@ -3104,6 +3176,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.6" @@ -3471,6 +3552,8 @@ dependencies = [ "rand 0.8.5", "reqwest", "rust-embed", + "sentry", + "sentry-log", "serde", "serde_json", "serde_repr", @@ -4099,6 +4182,15 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -4188,6 +4280,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_info" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +dependencies = [ + "log", + "serde", + "winapi", +] + [[package]] name = "os_str_bytes" version = "6.5.0" @@ -4569,7 +4672,7 @@ dependencies = [ "bitflags 1.3.2", "crc32fast", "flate2", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] @@ -5040,6 +5143,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -5286,6 +5395,136 @@ dependencies = [ "pest", ] +[[package]] +name = "sentry" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b0ad16faa5d12372f914ed40d00bda21a6d1bdcc99264c5e5e1c9495cf3654" +dependencies = [ + "httpdate", + "native-tls", + "reqwest", + "sentry-anyhow", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq", +] + +[[package]] +name = "sentry-anyhow" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3a571f02f9982af445af829c4837fe4857568a431bd2bed9f7cf88de4a6c44" +dependencies = [ + "anyhow", + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-backtrace" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f2ee8f147bb5f22ac59b5c35754a759b9a6f6722402e2a14750b2a63fc59bd" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcd133362c745151eeba0ac61e3ba8350f034e9fe7509877d08059fe1d7720c6" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7163491708804a74446642ff2c80b3acd668d4b9e9f497f85621f3d250fd012b" +dependencies = [ + "once_cell", + "rand 0.8.5", + "sentry-types", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-debug-images" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5003d7ff08aa3b2b76994080b183e8cfa06c083e280737c9cee02ca1c70f5e" +dependencies = [ + "findshlibs", + "once_cell", + "sentry-core", +] + +[[package]] +name = "sentry-log" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2558fc4a85326e6063711b45ce82ed6b18cdacd0732580c1567da914ac1df33e" +dependencies = [ + "log", + "sentry-core", +] + +[[package]] +name = "sentry-panic" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4dfe8371c9b2e126a8b64f6fefa54cef716ff2a50e63b5558a48b899265bccd" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca8b88978677a27ee1a91beafe4052306c474c06f582321fde72d2e2cc2f7f" +dependencies = [ + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e7a88e0c1922d19b3efee12a8215f6a8a806e442e665ada71cc222cab72985f" +dependencies = [ + "debugid", + "getrandom 0.2.10", + "hex", + "serde", + "serde_json", + "thiserror", + "time", + "url", + "uuid 1.3.0", +] + [[package]] name = "serde" version = "1.0.158" @@ -6773,6 +7012,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -6828,6 +7076,19 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "ureq" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +dependencies = [ + "base64 0.21.2", + "log", + "native-tls", + "once_cell", + "url", +] + [[package]] name = "url" version = "2.3.1" @@ -6865,6 +7126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom 0.2.10", + "serde", ] [[package]] diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index fb4b06a1df..bc89fd17ec 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -44,6 +44,8 @@ tokio = { version = "1.24.1", features = ["sync", "time"] } url = "2.2" yaml-rust = "0.4" toml = "0.7" +sentry = { version = "0.31.5", features = [ "anyhow" ] } +sentry-log = "0.31.5" nym-client-core = { path = "../../../common/client-core" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } diff --git a/nym-connect/desktop/src-tauri/src/logging.rs b/nym-connect/desktop/src-tauri/src/logging.rs index 3a6ee89e62..497813003d 100644 --- a/nym-connect/desktop/src-tauri/src/logging.rs +++ b/nym-connect/desktop/src-tauri/src/logging.rs @@ -1,4 +1,6 @@ use fern::colors::{Color, ColoredLevelConfig}; +use log::Level; +use sentry::Level as SentryLevel; use serde::Serialize; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::str::FromStr; @@ -22,7 +24,10 @@ fn formatted_time() -> String { _now.format(&format).unwrap() } -pub fn setup_logging(app_handle: tauri::AppHandle) -> Result<(), log::SetLoggerError> { +pub fn setup_logging( + app_handle: tauri::AppHandle, + monitoring: bool, +) -> Result<(), log::SetLoggerError> { let colors = ColoredLevelConfig::new() .trace(Color::Magenta) .debug(Color::Blue) @@ -61,6 +66,21 @@ pub fn setup_logging(app_handle: tauri::AppHandle) -> Result<(), log::SetLoggerE level: record.level().into(), }; app_handle.emit_all("log://log", msg).unwrap(); + })) + .chain(fern::Output::call(move |record| { + if !monitoring { + return; + } + let level = match record.level() { + Level::Error => SentryLevel::Error, + Level::Warn => SentryLevel::Warning, + Level::Info => SentryLevel::Info, + _ => SentryLevel::Debug, + }; + // only send error and warn logs to sentry + if let Level::Error | Level::Warn = record.level() { + sentry::capture_message(&record.args().to_string(), level); + }; })); base_config diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index 8a926938d1..de486c05de 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -25,6 +25,10 @@ mod state; mod tasks; mod window; +// TODO DSN shouldn't be hardcoded +const SENTRY_DSN: &str = + "https://68a2c55113ed47aaa30b9899039b0799@o967446.ingest.sentry.io/4505483113594880"; + fn main() { setup_env(None); println!("Starting up..."); @@ -32,7 +36,40 @@ fn main() { // As per breaking change description here // https://github.com/tauri-apps/tauri/blob/feac1d193c6d618e49916ad0707201f43d5cdd36/tooling/bundler/CHANGELOG.md if let Err(error) = fix_path_env::fix() { - log::warn!("Failed to fix PATH: {error}"); + println!("Failed to fix PATH: {error}"); + } + + let user_data = UserData::read().unwrap_or_else(|e| { + println!("{}", e); + println!("Fallback to default"); + UserData::default() + }); + + let monitoring = user_data.monitoring.unwrap_or(false); + + let _guard = sentry::init(( + SENTRY_DSN, + sentry::ClientOptions { + release: sentry::release_name!(), + sample_rate: 1.0, // TODO lower this in prod + traces_sample_rate: 1.0, + ..Default::default() // TODO add data scrubbing + // see https://docs.sentry.io/platforms/rust/data-management/sensitive-data/ + }, + )); + + sentry::configure_scope(|scope| { + scope.set_user(Some(sentry::User { + id: Some("nym".into()), + ..Default::default() + })); + }); + + if monitoring { + println!("Sentry reporting and monitoring is enabled"); + } else { + println!("Monitoring is disabled, dropping sentry guard"); + drop(_guard) } let user_data = UserData::read().unwrap_or_else(|e| { @@ -86,7 +123,7 @@ fn main() { ); } }) - .setup(|app| Ok(crate::logging::setup_logging(app.app_handle())?)) + .setup(move |app| Ok(crate::logging::setup_logging(app.app_handle(), monitoring)?)) .system_tray(create_tray_menu()) .on_system_tray_event(tray_menu_event_handler) .run(context) From feb888a154d058de71ee659104d6b65a67db0825 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Thu, 20 Jul 2023 17:20:00 +0200 Subject: [PATCH 28/59] updating sandbox .env --- envs/sandbox.env | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/envs/sandbox.env b/envs/sandbox.env index 1b25b72237..f42a91a97d 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -3,22 +3,22 @@ CONFIGURED=true RUST_LOG=info RUST_BACKTRACE=1 -BECH32_PREFIX=nymt -MIX_DENOM=unymt -MIX_DENOM_DISPLAY=nymt -STAKE_DENOM=unyxt -STAKE_DENOM_DISPLAY=nyxt +BECH32_PREFIX=n +MIX_DENOM=unym +MIX_DENOM_DISPLAY=nym +STAKE_DENOM=unyx +STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 -REWARDING_VALIDATOR_ADDRESS="nymt1mxuweurc066kprnngtm8zmvam7m2nw26yatpmv" -MIXNET_CONTRACT_ADDRESS="nymt1dlsvvgey26ernlj0sq2afjluh3qd4ap0k9eerekfkw5algqrwqksaf2qf7" -VESTING_CONTRACT_ADDRESS="nymt19g9xuqrvz2frv905v3fc7puryfypluhg383q9zwsmedrlqekfgys62ykm4" -BANDWIDTH_CLAIM_CONTRACT_ADDRESS="nymt1rhmk9udessnv3r8f3eh2s03f45svnjaczpmcqz" -MULTISIG_CONTRACT_ADDRESS="nymt142dkm8xe9f0ytyarp7ww4kvclva65705jphxsk9exn3nqdsm8jkqnp06ac" -COCONUT_BANDWIDTH_CONTRACT_ADDRESS="nymt1ty0frysegskh6ndm3v96z5xdq66qzcu0aw7xcxlgp54jg0mjwlgqplc6v0" -COCONUT_DKG_CONTRACT_ADDRESS="nymt1gwk6muhmzeuxje7df7rjvqwl2vex0kj4t2hwuzmyx5k62kfusu5qk4k5z4" -GROUP_CONTRACT_ADDRESS="nymt14ry36mwauycz08v8ndcujghxz4hmua5epxcn0mamlr3suqe0l2qsqx5ya2" +REWARDING_VALIDATOR_ADDRESS=n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa +MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav +VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz +BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 +COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l +GROUP_CONTRACT_ADDRESS=n1pd7kfgvr5tpcv0xnlv46c4jsq9jg2r799xxrcwqdm4l2jhq2pjwqrmz5ju +MULTISIG_CONTRACT_ADDRESS=n14ph4e660eyqz0j36zlkaey4zgzexm5twkmjlqaequxr2cjm9eprqsmad6k +COCONUT_DKG_CONTRACT_ADDRESS=n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" NYXD="https://sandbox-validator1.nymtech.net" -NYM_API="https://sandbox-validator1-api.nymtech.net/api" \ No newline at end of file +NYM_API="https://sandbox-nym-api1.nymtech.net/api" \ No newline at end of file From dff11df2bdfeb23df75607145f2f83d75afc09ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Fri, 21 Jul 2023 13:25:14 +0300 Subject: [PATCH 29/59] Add DKG resharing benchmark (#3692) * Add DKG resharing benchmark * Fix clippy --- common/dkg/benches/benchmarks.rs | 124 ++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/common/dkg/benches/benchmarks.rs b/common/dkg/benches/benchmarks.rs index 0aed2e4192..483c6d20e9 100644 --- a/common/dkg/benches/benchmarks.rs +++ b/common/dkg/benches/benchmarks.rs @@ -10,10 +10,10 @@ use nym_dkg::bte::proof_discrete_log::ProofOfDiscreteLog; use nym_dkg::bte::proof_sharing::ProofOfSecretSharing; use nym_dkg::bte::{ decrypt_share, encrypt_shares, keygen, proof_chunking, proof_sharing, setup, DecryptionKey, - PublicKey, + Params, PublicKey, }; use nym_dkg::interpolation::polynomial::Polynomial; -use nym_dkg::{Dealing, NodeIndex, Share}; +use nym_dkg::{combine_shares, Dealing, NodeIndex, Share, Threshold}; use rand_core::{RngCore, SeedableRng}; use std::collections::BTreeMap; @@ -49,6 +49,37 @@ fn prepare_keys( (receivers, dks) } +fn prepare_resharing( + mut rng: impl RngCore, + params: &Params, + nodes: usize, + threshold: Threshold, +) -> (BTreeMap, Vec) { + let (receivers, mut dks) = prepare_keys(&mut rng, nodes); + + let first_dealings = receivers + .keys() + .map(|&dealer_index| { + Dealing::create(&mut rng, params, dealer_index, threshold, &receivers, None).0 + }) + .collect::>(); + + let mut derived_secrets = Vec::new(); + for (i, ref mut dk) in dks.iter_mut().enumerate() { + let shares = first_dealings + .iter() + .map(|dealing| decrypt_share(dk, i, &dealing.ciphertexts, None).unwrap()) + .collect(); + + let recovered_secret = + combine_shares(shares, &receivers.keys().copied().collect::>()).unwrap(); + + derived_secrets.push(recovered_secret) + } + + (receivers, derived_secrets) +} + pub fn creating_dealing_for_3_parties(c: &mut Criterion) { let dummy_seed = [42u8; 32]; let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); @@ -73,6 +104,33 @@ pub fn creating_dealing_for_3_parties(c: &mut Criterion) { }); } +pub fn creating_reshared_dealing_for_3_parties(c: &mut Criterion) { + let dummy_seed = [42u8; 32]; + let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); + let params = setup(); + let threshold = 2; + + let (receivers, mut derived_secrets) = prepare_resharing(&mut rng, ¶ms, 3, threshold); + + c.bench_function( + "creating single re-shared dealing for 3 parties (threshold 2)", + |b| { + b.iter(|| { + black_box({ + Dealing::create( + &mut rng, + ¶ms, + receivers.keys().next().copied().unwrap(), + threshold, + &receivers, + Some(derived_secrets.pop().unwrap()), + ) + }) + }) + }, + ); +} + pub fn verifying_dealing_made_for_3_parties_and_recovering_share(c: &mut Criterion) { let dummy_seed = [42u8; 32]; let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); @@ -129,6 +187,33 @@ pub fn creating_dealing_for_20_parties(c: &mut Criterion) { ); } +pub fn creating_reshared_dealing_for_20_parties(c: &mut Criterion) { + let dummy_seed = [42u8; 32]; + let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); + let params = setup(); + let threshold = 14; + + let (receivers, mut derived_secrets) = prepare_resharing(&mut rng, ¶ms, 20, threshold); + + c.bench_function( + "creating single re-shared dealing for 20 parties (threshold 14)", + |b| { + b.iter(|| { + black_box({ + Dealing::create( + &mut rng, + ¶ms, + receivers.keys().next().copied().unwrap(), + threshold, + &receivers, + Some(derived_secrets.pop().unwrap()), + ) + }) + }) + }, + ); +} + pub fn verifying_dealing_made_for_20_parties_and_recovering_share(c: &mut Criterion) { let dummy_seed = [42u8; 32]; let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); @@ -185,6 +270,33 @@ pub fn creating_dealing_for_100_parties(c: &mut Criterion) { ); } +pub fn creating_reshared_dealing_for_100_parties(c: &mut Criterion) { + let dummy_seed = [42u8; 32]; + let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); + let params = setup(); + let threshold = 67; + + let (receivers, mut derived_secrets) = prepare_resharing(&mut rng, ¶ms, 100, threshold); + + c.bench_function( + "creating single re-shared dealing for 100 parties (threshold 67)", + |b| { + b.iter(|| { + black_box({ + Dealing::create( + &mut rng, + ¶ms, + receivers.keys().next().copied().unwrap(), + threshold, + &receivers, + Some(derived_secrets.pop().unwrap()), + ) + }) + }) + }, + ); +} + pub fn verifying_dealing_made_for_100_parties_and_recovering_share(c: &mut Criterion) { let dummy_seed = [42u8; 32]; let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed); @@ -472,6 +584,13 @@ criterion_group!( creating_dealing_for_100_parties, ); +criterion_group!( + reshared_dealings_creation, + creating_reshared_dealing_for_3_parties, + creating_reshared_dealing_for_20_parties, + creating_reshared_dealing_for_100_parties, +); + // note: in our setting each party will have to create at least 4 dealings (one per attribute in credential) // and verify 99 * 4 of them (4 from each other dealer) criterion_group!( @@ -501,6 +620,7 @@ criterion_group!( criterion_main!( utils, dealings_creation, + reshared_dealings_creation, dealings_verification, proofs_of_knowledge, encryption From 34a47a9449d5c3c4a8f4270dcb9f0a004972c752 Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 21 Jul 2023 15:56:08 +0200 Subject: [PATCH 30/59] build(nc-desktop): sentry dsn as env var --- .../workflows/nym-connect-publish-macos.yml | 2 + .../workflows/nym-connect-publish-ubuntu.yml | 2 + .../nym-connect-publish-windows10.yml | 2 + nym-connect/desktop/Cargo.lock | 5 +- nym-connect/desktop/src-tauri/Cargo.toml | 1 + nym-connect/desktop/src-tauri/src/build.rs | 13 +++++ .../desktop/src-tauri/src/constants.rs | 3 ++ nym-connect/desktop/src-tauri/src/main.rs | 48 +++++++------------ .../desktop/src-tauri/src/monitoring.rs | 38 +++++++++++++++ nym-connect/desktop/src/sentry.ts | 12 ++++- 10 files changed, 90 insertions(+), 36 deletions(-) create mode 100644 nym-connect/desktop/src-tauri/src/constants.rs create mode 100644 nym-connect/desktop/src-tauri/src/monitoring.rs diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index bd15cf1554..9f103aeb11 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -78,6 +78,8 @@ jobs: APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }} + SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }} run: yarn && yarn build - name: Upload Artifact diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index 70068778f5..fb0c0eec4b 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -61,6 +61,8 @@ jobs: env: TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }} + SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }} - name: Upload Artifact uses: actions/upload-artifact@v3 diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index db152e4e69..ca6f6aef01 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -79,6 +79,8 @@ jobs: WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }} + SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }} run: yarn build - name: Upload Artifact diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 18ef59a2d7..89bfdbc8f3 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1414,9 +1414,9 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "dotenvy" -version = "0.15.6" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "dtoa" @@ -3532,6 +3532,7 @@ dependencies = [ "anyhow", "bip39", "dirs 4.0.0", + "dotenvy", "eyre", "fern", "fix-path-env", diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index bc89fd17ec..edce6a2bb6 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -46,6 +46,7 @@ yaml-rust = "0.4" toml = "0.7" sentry = { version = "0.31.5", features = [ "anyhow" ] } sentry-log = "0.31.5" +dotenvy = "0.15.7" nym-client-core = { path = "../../../common/client-core" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } diff --git a/nym-connect/desktop/src-tauri/src/build.rs b/nym-connect/desktop/src-tauri/src/build.rs index 261851f6b6..7c65873b94 100644 --- a/nym-connect/desktop/src-tauri/src/build.rs +++ b/nym-connect/desktop/src-tauri/src/build.rs @@ -1,3 +1,16 @@ +use std::env; + +mod constants; + +use constants::{SENTRY_DSN_JS, SENTRY_DSN_RUST}; + fn main() { + // set these env vars at compile time + if let Ok(dsn) = env::var(SENTRY_DSN_RUST) { + println!("cargo:rustc-env={}={}", SENTRY_DSN_RUST, dsn); + } + if let Ok(dsn) = env::var(SENTRY_DSN_JS) { + println!("cargo:rustc-env={}={}", SENTRY_DSN_JS, dsn); + } tauri_build::build(); } diff --git a/nym-connect/desktop/src-tauri/src/constants.rs b/nym-connect/desktop/src-tauri/src/constants.rs new file mode 100644 index 0000000000..379fa02be8 --- /dev/null +++ b/nym-connect/desktop/src-tauri/src/constants.rs @@ -0,0 +1,3 @@ +// env var keys +pub const SENTRY_DSN_RUST: &str = "SENTRY_DSN_RUST"; +pub const SENTRY_DSN_JS: &str = "SENTRY_DSN_JS"; diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index de486c05de..02981ee1ee 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -3,6 +3,7 @@ windows_subsystem = "windows" )] +use std::env; use std::sync::Arc; use nym_config::defaults::setup_env; @@ -15,21 +16,20 @@ use crate::state::State; use crate::window::window_toggle; mod config; +mod constants; mod error; mod events; mod logging; mod menu; mod models; +mod monitoring; mod operations; mod state; mod tasks; mod window; -// TODO DSN shouldn't be hardcoded -const SENTRY_DSN: &str = - "https://68a2c55113ed47aaa30b9899039b0799@o967446.ingest.sentry.io/4505483113594880"; - fn main() { + dotenvy::dotenv().ok(); setup_env(None); println!("Starting up..."); @@ -46,37 +46,21 @@ fn main() { }); let monitoring = user_data.monitoring.unwrap_or(false); - - let _guard = sentry::init(( - SENTRY_DSN, - sentry::ClientOptions { - release: sentry::release_name!(), - sample_rate: 1.0, // TODO lower this in prod - traces_sample_rate: 1.0, - ..Default::default() // TODO add data scrubbing - // see https://docs.sentry.io/platforms/rust/data-management/sensitive-data/ - }, - )); - - sentry::configure_scope(|scope| { - scope.set_user(Some(sentry::User { - id: Some("nym".into()), - ..Default::default() - })); - }); + let mut _sentry_guard; if monitoring { - println!("Sentry reporting and monitoring is enabled"); - } else { - println!("Monitoring is disabled, dropping sentry guard"); - drop(_guard) - } + match monitoring::init() { + Ok(guard) => { + println!("Monitoring and error reporting enabled"); - let user_data = UserData::read().unwrap_or_else(|e| { - println!("{}", e); - println!("Fallback to default"); - UserData::default() - }); + // we must keep the sentry guard in scope during app lifetime + _sentry_guard = guard; + } + Err(e) => { + println!("Unable to init monitoring: {e}"); + } + } + } let context = tauri::generate_context!(); tauri::Builder::default() diff --git a/nym-connect/desktop/src-tauri/src/monitoring.rs b/nym-connect/desktop/src-tauri/src/monitoring.rs new file mode 100644 index 0000000000..e4555f3277 --- /dev/null +++ b/nym-connect/desktop/src-tauri/src/monitoring.rs @@ -0,0 +1,38 @@ +use std::env; + +use anyhow::{Context, Result}; +use sentry::ClientInitGuard; + +use crate::constants::{SENTRY_DSN_JS, SENTRY_DSN_RUST}; + +pub fn init() -> Result { + // if these env vars were set at compile time, use their value + if let Some(v) = option_env!("SENTRY_DSN_RUST") { + env::set_var(SENTRY_DSN_RUST, v); + } + if let Some(v) = option_env!("SENTRY_DSN_JS") { + env::set_var(SENTRY_DSN_JS, v); + } + + let dsn = env::var(SENTRY_DSN_RUST).context(format!("{} env var not set", SENTRY_DSN_RUST))?; + println!("using DSN {dsn}"); + let guard = sentry::init(( + dsn, + sentry::ClientOptions { + release: sentry::release_name!(), + sample_rate: 1.0, // TODO lower this in prod + traces_sample_rate: 1.0, + ..Default::default() // TODO add data scrubbing + // see https://docs.sentry.io/platforms/rust/data-management/sensitive-data/ + }, + )); + + sentry::configure_scope(|scope| { + scope.set_user(Some(sentry::User { + id: Some("nym".into()), + ..Default::default() + })); + }); + + Ok(guard) +} diff --git a/nym-connect/desktop/src/sentry.ts b/nym-connect/desktop/src/sentry.ts index 13f7529c30..5127c5dc0c 100644 --- a/nym-connect/desktop/src/sentry.ts +++ b/nym-connect/desktop/src/sentry.ts @@ -1,17 +1,25 @@ import React from 'react'; import { createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router-dom'; +import { invoke } from '@tauri-apps/api'; import * as Sentry from '@sentry/react'; import { CaptureConsole } from '@sentry/integrations'; import { getVersion } from '@tauri-apps/api/app'; -const SENTRY_DSN = 'https://625e2658da4945a7a253f3ee04413a31@o967446.ingest.sentry.io/4505306292289536'; +const SENTRY_DSN = 'SENTRY_DSN_JS'; async function initSentry() { console.log('⚠ performance monitoring and error reporting enabled'); console.log('initializing sentry'); + const dsn = await invoke('get_env', { variable: SENTRY_DSN }); + + if (!dsn) { + console.warn(`unable to initialize sentry, ${SENTRY_DSN} env var not set`); + return; + } + Sentry.init({ - dsn: SENTRY_DSN, + dsn, integrations: [ new Sentry.BrowserTracing({ // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled From f1175280cfedc69590b184ce36b670e986525cfc Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Mon, 26 Jun 2023 12:17:52 +0100 Subject: [PATCH 31/59] add warning to tx modals when fee exceeds balance --- .../Bonding/modals/RedeemRewardsModal.tsx | 13 +- .../components/Delegation/UndelegateModal.tsx | 10 +- .../src/components/FeeWarning.stories.tsx | 27 ++ nym-wallet/src/components/FeeWarning.tsx | 19 +- .../src/components/Rewards/RedeemModal.tsx | 13 +- nym-wallet/src/pages/delegation/index.tsx | 1 - nym-wallet/src/utils/generalUtils.ts | 245 ++++++++++++++++++ nym-wallet/src/utils/index.ts | 233 +---------------- 8 files changed, 321 insertions(+), 240 deletions(-) create mode 100644 nym-wallet/src/components/FeeWarning.stories.tsx create mode 100644 nym-wallet/src/utils/generalUtils.ts diff --git a/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx b/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx index 76b9192df9..88490e7e0e 100644 --- a/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx @@ -1,11 +1,13 @@ -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { FeeDetails } from '@nymproject/types'; import { ModalListItem } from 'src/components/Modals/ModalListItem'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { ModalFee } from 'src/components/Modals/ModalFee'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateClaimOperatorReward, simulateVestingClaimOperatorReward } from 'src/requests'; -import { TBondedMixnode } from 'src/context'; +import { AppContext, TBondedMixnode } from 'src/context'; +import { BalanceWarning } from 'src/components/FeeWarning'; +import { Box } from '@mui/material'; export const RedeemRewardsModal = ({ node, @@ -19,6 +21,7 @@ export const RedeemRewardsModal = ({ onClose: () => void; }) => { const { fee, getFee, isFeeLoading, feeError } = useGetFee(); + const { userBalance } = useContext(AppContext); useEffect(() => { if (feeError) onError(feeError); @@ -49,7 +52,13 @@ export const RedeemRewardsModal = ({ divider /> + + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + + )} ); }; diff --git a/nym-wallet/src/components/Delegation/UndelegateModal.tsx b/nym-wallet/src/components/Delegation/UndelegateModal.tsx index fe518d37ff..12662ef3d5 100644 --- a/nym-wallet/src/components/Delegation/UndelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/UndelegateModal.tsx @@ -1,11 +1,13 @@ import { Box, SxProps } from '@mui/material'; -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { FeeDetails } from '@nymproject/types'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateUndelegateFromMixnode, simulateVestingUndelegateFromMixnode } from 'src/requests'; +import { AppContext } from 'src/context'; import { ModalFee } from '../Modals/ModalFee'; import { ModalListItem } from '../Modals/ModalListItem'; import { SimpleModal } from '../Modals/SimpleModal'; +import { BalanceWarning } from '../FeeWarning'; export const UndelegateModal: FCWithChildren<{ open: boolean; @@ -20,6 +22,7 @@ export const UndelegateModal: FCWithChildren<{ backdropProps?: object; }> = ({ mixId, identityKey, open, onClose, onOk, amount, currency, usesVestingContractTokens, sx, backdropProps }) => { const { fee, isFeeLoading, feeError, getFee } = useGetFee(); + const { userBalance } = useContext(AppContext); useEffect(() => { if (usesVestingContractTokens) getFee(simulateVestingUndelegateFromMixnode, { mixId }); @@ -50,6 +53,11 @@ export const UndelegateModal: FCWithChildren<{ + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + + )} ); diff --git a/nym-wallet/src/components/FeeWarning.stories.tsx b/nym-wallet/src/components/FeeWarning.stories.tsx new file mode 100644 index 0000000000..9202ecc300 --- /dev/null +++ b/nym-wallet/src/components/FeeWarning.stories.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import { Box } from '@mui/material'; +import { BalanceWarning } from './FeeWarning'; + +export default { + title: 'Wallet / Balance warning', + component: BalanceWarning, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + + + +); + +export const WithWarning = Template.bind({}); +WithWarning.args = { + balance: '100', + fee: '200', +}; + +export const NoWarning = Template.bind({}); +NoWarning.args = { + balance: '100', + fee: '100', +}; diff --git a/nym-wallet/src/components/FeeWarning.tsx b/nym-wallet/src/components/FeeWarning.tsx index b26a7f8369..8f22a07591 100644 --- a/nym-wallet/src/components/FeeWarning.tsx +++ b/nym-wallet/src/components/FeeWarning.tsx @@ -1,16 +1,31 @@ import React from 'react'; import { Warning } from '@mui/icons-material'; import { FeeDetails } from '@nymproject/types'; -import { Alert, AlertTitle } from '@mui/material'; +import { Alert, AlertTitle, Box } from '@mui/material'; +import { isBalanceEnough } from 'src/utils'; export const FeeWarning = ({ fee, amount }: { fee: FeeDetails; amount: number }) => { if (fee.amount && +fee.amount.amount > amount) { return ( }> - Warning: fees are greater than the reward + Warning: Fees are greater than the reward The fees for redeeming rewards will cost more than the rewards. Are you sure you want to continue? ); } return null; }; + +export const BalanceWarning = ({ balance, fee }: { balance: string; fee: string }) => { + const hasEnoughBalanace = isBalanceEnough(balance, fee); + + if (!balance || !fee || hasEnoughBalanace) return null; + + return ( + }> + Warning: Fees are greater than your balance + The fess are greater than your current balance which cause this transaction to fail. + Do you want to continue? + + ); +}; diff --git a/nym-wallet/src/components/Rewards/RedeemModal.tsx b/nym-wallet/src/components/Rewards/RedeemModal.tsx index 9d80a5d048..ec6bde1846 100644 --- a/nym-wallet/src/components/Rewards/RedeemModal.tsx +++ b/nym-wallet/src/components/Rewards/RedeemModal.tsx @@ -1,12 +1,13 @@ -import React, { useEffect } from 'react'; +import React, { useContext, useEffect } from 'react'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyDenom, FeeDetails } from '@nymproject/types'; -import { SxProps } from '@mui/material'; +import { Box, SxProps } from '@mui/material'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateClaimDelegatorReward, simulateVestingClaimDelegatorReward } from 'src/requests'; +import { AppContext } from 'src/context'; import { ModalFee } from '../Modals/ModalFee'; import { SimpleModal } from '../Modals/SimpleModal'; -import { FeeWarning } from '../FeeWarning'; +import { BalanceWarning, FeeWarning } from '../FeeWarning'; import { ModalListItem } from '../Modals/ModalListItem'; export const RedeemModal: FCWithChildren<{ @@ -23,6 +24,7 @@ export const RedeemModal: FCWithChildren<{ usesVestingTokens: boolean; }> = ({ open, onClose, onOk, mixId, identityKey, amount, denom, message, usesVestingTokens, sx, backdropProps }) => { const { fee, isFeeLoading, feeError, getFee } = useGetFee(); + const { userBalance } = useContext(AppContext); const handleOk = async () => { if (onOk) { @@ -56,6 +58,11 @@ export const RedeemModal: FCWithChildren<{ {fee && } + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + + )} ); }; diff --git a/nym-wallet/src/pages/delegation/index.tsx b/nym-wallet/src/pages/delegation/index.tsx index ce5156aee5..77f0db7091 100644 --- a/nym-wallet/src/pages/delegation/index.tsx +++ b/nym-wallet/src/pages/delegation/index.tsx @@ -249,7 +249,6 @@ export const Delegation: FC<{ isStorybook?: boolean }> = ({ isStorybook }) => { tx = await undelegate(mixId, fee?.fee); } - // const txs = await undelegate(mixId, usesVestingContractTokens, fee); const balances = await getAllBalances(); setConfirmationModalProps({ diff --git a/nym-wallet/src/utils/generalUtils.ts b/nym-wallet/src/utils/generalUtils.ts new file mode 100644 index 0000000000..39366fa724 --- /dev/null +++ b/nym-wallet/src/utils/generalUtils.ts @@ -0,0 +1,245 @@ +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 { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types'; +import { TPoolOption } from 'src/components'; +import { + getCurrentInterval, + getDefaultMixnodeCostParams, + getLockedCoins, + getSpendableCoins, + userBalance, +} from '../requests'; +import { Console } from './console'; + +export const validateKey = (key: string, bytesLength: number): boolean => { + // it must be a valid base58 key + try { + const bytes = bs58.decode(key); + // of length 32 + return bytes.length === bytesLength; + } catch (e) { + Console.error(e as string); + return false; + } +}; + +export const validateAmount = async ( + majorAmountAsString: DecCoin['amount'], + minimumAmountAsString: DecCoin['amount'], +): Promise => { + // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc + if (!Number(majorAmountAsString)) { + return false; + } + + if (!isValidRawCoin(majorAmountAsString)) { + return false; + } + + const majorValueFloat = parseInt(majorAmountAsString, Number(10)); + + return majorValueFloat >= parseInt(minimumAmountAsString, Number(10)); + + // this conversion seems really iffy but I'm not sure how to better approach it +}; + +export const isValidHostname = (value: string) => { + // regex for ipv4 and ipv6 and hhostname- source http://jsfiddle.net/DanielD/8S4nq/ + const hostnameRegex = + /((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))|(^\s*((?=.{1,255}$)(?=.*[A-Za-z].*)[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?)*)\s*$)/; + + return hostnameRegex.test(value); +}; + +export const validateVersion = (version: string): boolean => { + try { + return valid(version) !== null; + } catch (e) { + return false; + } +}; + +export const validateLocation = (location: string): boolean => { + const locationRegex = /^[a-z]+$/i; + return locationRegex.test(location); +}; + +export const validateRawPort = (rawPort: number): boolean => !Number.isNaN(rawPort) && rawPort >= 1 && rawPort <= 65535; + +export const truncate = (text: string, trim: number) => `${text.substring(0, trim)}...`; + +export const isGreaterThan = (a: number, b: number) => a > b; + +export const isLessThan = (a: number, b: number) => a < b; + +export const checkHasEnoughFunds = async (allocationValue: string): Promise => { + try { + const walletValue = await userBalance(); + + const remainingBalance = +walletValue.amount.amount - +allocationValue; + return remainingBalance >= 0; + } catch (e) { + Console.log(e as string); + return false; + } +}; + +export const checkHasEnoughLockedTokens = async (allocationValue: string) => { + try { + const lockedTokens = await getLockedCoins(); + const spendableTokens = await getSpendableCoins(); + const remainingBalance = +lockedTokens.amount + +spendableTokens.amount - +allocationValue; + return remainingBalance >= 0; + } catch (e) { + Console.error(e as string); + } + return false; +}; + +export const randomNumberBetween = (min: number, max: number) => { + const minCeil = Math.ceil(min); + const maxFloor = Math.floor(max); + return Math.floor(Math.random() * (maxFloor - minCeil + 1) + minCeil); +}; + +export const splice = (size: number, address?: string): string => { + if (address) { + return `${address.slice(0, size)}...${address.slice(-size)}`; + } + return ''; +}; + +export const maximizeWindow = async () => { + await appWindow.maximize(); +}; + +export function removeObjectDuplicates(arr: T[], id: K) { + return arr.filter((v, i, a) => a.findIndex((v2) => v2[id] === v[id]) === i); +} + +export const checkTokenBalance = async (tokenPool: TPoolOption, amount: string) => { + let hasEnoughFunds = false; + if (tokenPool === 'locked') { + hasEnoughFunds = await checkHasEnoughLockedTokens(amount); + } + + if (tokenPool === 'balance') { + hasEnoughFunds = await checkHasEnoughFunds(amount); + } + + return hasEnoughFunds; +}; + +export const isDecimal = (value: number) => value - Math.floor(value) !== 0; + +export const attachDefaultOperatingCost = async (profitMarginPercent: string): Promise => + getDefaultMixnodeCostParams(profitMarginPercent); + +/** + * Converts a stringified percentage integer (0-100) to a stringified float (0.0-1.0). + * + * @param value - the percentage to convert + * @returns A stringified float + */ +export const toPercentFloatString = (value: string) => (Number(value) / 100).toString(); + +/** + * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100). + * + * @param value - the percentage to convert + * @returns A stringified integer + */ +export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString(); + +/** + * Converts a decimal number to a pretty representation + * with fixed decimal places. + * + * @param val - a decimal number of string form + * @param dp - number of decimal places (4 by default ie. 0.0000) + * @returns A prettified decimal number + */ +export const toDisplay = (val: string | number | Big, dp = 4) => { + let displayValue; + try { + displayValue = Big(val).toFixed(dp); + } catch (e: any) { + Console.warn(`${displayValue} not a valid decimal number: ${e}`); + } + return displayValue; +}; + +/** + * Takes a DecCoin and prettify its amount to a representation + * with fixed decimal places. + * + * @param coin - a DecCoin + * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000) + * @returns A DecCoin with prettified amount + */ +export const decCoinToDisplay = (coin: DecCoin, dp = 4) => { + const displayCoin = { ...coin }; + try { + displayCoin.amount = Big(coin.amount).toFixed(dp); + } catch (e: any) { + Console.warn(`${coin.amount} not a valid decimal number: ${e}`); + } + return displayCoin; +}; + +/** + * Converts a decimal number of μNYM (micro NYM) to NYM. + * + * @param unym - string representation of a decimal number of μNYM + * @param dp - number of decimal places (4 by default ie. 0.0000) + * @returns The corresponding decimal number in NYM + */ +export const unymToNym = (unym: string | Big, dp = 4) => { + let nym; + try { + nym = Big(unym).div(1_000_000).toFixed(dp); + } catch (e: any) { + Console.warn(`${unym} not a valid decimal number: ${e}`); + } + return nym; +}; + +/** + * + * Checks if the user's balance is enough to pay the fee + * @param balance - The user's balance to check + * @param fee - The fee to check + * @returns boolean + * + */ + +export const isBalanceEnough = (balance: string, fee: string) => { + if (!fee || !userBalance) return false; + if (!balance) return false; + return Number(balance) >= Number(fee); +}; + +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/index.ts b/nym-wallet/src/utils/index.ts index 1f713a7b1d..e0e8ee8101 100644 --- a/nym-wallet/src/utils/index.ts +++ b/nym-wallet/src/utils/index.ts @@ -1,233 +1,4 @@ -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 { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types'; -import { TPoolOption } from 'src/components'; -import { - getCurrentInterval, - getDefaultMixnodeCostParams, - getLockedCoins, - getSpendableCoins, - userBalance, -} from '../requests'; -import { Console } from './console'; - -export const validateKey = (key: string, bytesLength: number): boolean => { - // it must be a valid base58 key - try { - const bytes = bs58.decode(key); - // of length 32 - return bytes.length === bytesLength; - } catch (e) { - Console.error(e as string); - return false; - } -}; - -export const validateAmount = async ( - majorAmountAsString: DecCoin['amount'], - minimumAmountAsString: DecCoin['amount'], -): Promise => { - // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc - if (!Number(majorAmountAsString)) { - return false; - } - - if (!isValidRawCoin(majorAmountAsString)) { - return false; - } - - const majorValueFloat = parseInt(majorAmountAsString, Number(10)); - - return majorValueFloat >= parseInt(minimumAmountAsString, Number(10)); - - // this conversion seems really iffy but I'm not sure how to better approach it -}; - -export const isValidHostname = (value: string) => { - // regex for ipv4 and ipv6 and hhostname- source http://jsfiddle.net/DanielD/8S4nq/ - const hostnameRegex = - /((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))|(^\s*((?=.{1,255}$)(?=.*[A-Za-z].*)[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?)*)\s*$)/; - - return hostnameRegex.test(value); -}; - -export const validateVersion = (version: string): boolean => { - try { - return valid(version) !== null; - } catch (e) { - return false; - } -}; - -export const validateLocation = (location: string): boolean => { - const locationRegex = /^[a-z]+$/i; - return locationRegex.test(location); -}; - -export const validateRawPort = (rawPort: number): boolean => !Number.isNaN(rawPort) && rawPort >= 1 && rawPort <= 65535; - -export const truncate = (text: string, trim: number) => `${text.substring(0, trim)}...`; - -export const isGreaterThan = (a: number, b: number) => a > b; - -export const isLessThan = (a: number, b: number) => a < b; - -export const checkHasEnoughFunds = async (allocationValue: string): Promise => { - try { - const walletValue = await userBalance(); - - const remainingBalance = +walletValue.amount.amount - +allocationValue; - return remainingBalance >= 0; - } catch (e) { - Console.log(e as string); - return false; - } -}; - -export const checkHasEnoughLockedTokens = async (allocationValue: string) => { - try { - const lockedTokens = await getLockedCoins(); - const spendableTokens = await getSpendableCoins(); - const remainingBalance = +lockedTokens.amount + +spendableTokens.amount - +allocationValue; - return remainingBalance >= 0; - } catch (e) { - Console.error(e as string); - } - return false; -}; - -export const randomNumberBetween = (min: number, max: number) => { - const minCeil = Math.ceil(min); - const maxFloor = Math.floor(max); - return Math.floor(Math.random() * (maxFloor - minCeil + 1) + minCeil); -}; - -export const splice = (size: number, address?: string): string => { - if (address) { - return `${address.slice(0, size)}...${address.slice(-size)}`; - } - return ''; -}; - -export const maximizeWindow = async () => { - await appWindow.maximize(); -}; - -export function removeObjectDuplicates(arr: T[], id: K) { - return arr.filter((v, i, a) => a.findIndex((v2) => v2[id] === v[id]) === i); -} - -export const checkTokenBalance = async (tokenPool: TPoolOption, amount: string) => { - let hasEnoughFunds = false; - if (tokenPool === 'locked') { - hasEnoughFunds = await checkHasEnoughLockedTokens(amount); - } - - if (tokenPool === 'balance') { - hasEnoughFunds = await checkHasEnoughFunds(amount); - } - - return hasEnoughFunds; -}; - -export const isDecimal = (value: number) => value - Math.floor(value) !== 0; - -export const attachDefaultOperatingCost = async (profitMarginPercent: string): Promise => - getDefaultMixnodeCostParams(profitMarginPercent); - -/** - * Converts a stringified percentage integer (0-100) to a stringified float (0.0-1.0). - * - * @param value - the percentage to convert - * @returns A stringified float - */ -export const toPercentFloatString = (value: string) => (Number(value) / 100).toString(); - -/** - * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100). - * - * @param value - the percentage to convert - * @returns A stringified integer - */ -export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString(); - -/** - * Converts a decimal number to a pretty representation - * with fixed decimal places. - * - * @param val - a decimal number of string form - * @param dp - number of decimal places (4 by default ie. 0.0000) - * @returns A prettified decimal number - */ -export const toDisplay = (val: string | number | Big, dp = 4) => { - let displayValue; - try { - displayValue = Big(val).toFixed(dp); - } catch (e: any) { - Console.warn(`${displayValue} not a valid decimal number: ${e}`); - } - return displayValue; -}; - -/** - * Takes a DecCoin and prettify its amount to a representation - * with fixed decimal places. - * - * @param coin - a DecCoin - * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000) - * @returns A DecCoin with prettified amount - */ -export const decCoinToDisplay = (coin: DecCoin, dp = 4) => { - const displayCoin = { ...coin }; - try { - displayCoin.amount = Big(coin.amount).toFixed(dp); - } catch (e: any) { - Console.warn(`${coin.amount} not a valid decimal number: ${e}`); - } - return displayCoin; -}; - -/** - * Converts a decimal number of μNYM (micro NYM) to NYM. - * - * @param unym - string representation of a decimal number of μNYM - * @param dp - number of decimal places (4 by default ie. 0.0000) - * @returns The corresponding decimal number in NYM - */ -export const unymToNym = (unym: string | Big, dp = 4) => { - let nym; - try { - nym = Big(unym).div(1_000_000).toFixed(dp); - } catch (e: any) { - Console.warn(`${unym} not a valid decimal number: ${e}`); - } - 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 }; -}; - +export * from './generalUtils'; export * from './fireRequests'; +export * from './console'; export { default as fireRequests } from './fireRequests'; From eadd116ae4acdb356881e9c88382422f3ac7715e Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Mon, 26 Jun 2023 14:50:49 +0100 Subject: [PATCH 32/59] add warning modal for more txs --- .../Bonding/modals/UpdateBondAmountModal.tsx | 8 +++++++- nym-wallet/src/components/Delegation/DelegateModal.tsx | 10 +++++++++- .../src/components/Delegation/UndelegateModal.tsx | 2 +- nym-wallet/src/components/FeeWarning.tsx | 2 +- nym-wallet/src/hooks/useGetBalance.ts | 6 +++--- nym-wallet/src/utils/{generalUtils.ts => common.ts} | 0 nym-wallet/src/utils/index.ts | 2 +- 7 files changed, 22 insertions(+), 8 deletions(-) rename nym-wallet/src/utils/{generalUtils.ts => common.ts} (100%) diff --git a/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx b/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx index 552f2b1f4c..07be4bcf47 100644 --- a/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx @@ -11,6 +11,7 @@ import { decCoinToDisplay, validateAmount } from 'src/utils'; import { simulateUpdateBond, simulateVestingUpdateBond } from 'src/requests'; import { TSimulateUpdateBondArgs, TUpdateBondArgs } from 'src/types'; import { AppContext, TBondedMixnode } from 'src/context'; +import { BalanceWarning } from 'src/components/FeeWarning'; import { TPoolOption } from '../../TokenPoolSelector'; export const UpdateBondAmountModal = ({ @@ -30,7 +31,7 @@ export const UpdateBondAmountModal = ({ const [newBond, setNewBond] = useState(); const [errorAmount, setErrorAmount] = useState(false); - const { printBalance, printVestedBalance } = useContext(AppContext); + const { printBalance, printVestedBalance, userBalance } = useContext(AppContext); useEffect(() => { if (feeError) { @@ -104,6 +105,11 @@ export const UpdateBondAmountModal = ({ > + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + + )} ); diff --git a/nym-wallet/src/components/Delegation/DelegateModal.tsx b/nym-wallet/src/components/Delegation/DelegateModal.tsx index 61762357de..12d076f7c8 100644 --- a/nym-wallet/src/components/Delegation/DelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/DelegateModal.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useContext, useState } from 'react'; import { Box, Typography, SxProps } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; @@ -7,6 +7,7 @@ import { Console } from 'src/utils/console'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateDelegateToMixnode, simulateVestingDelegateToMixnode, tryConvertIdentityToMixId } from 'src/requests'; import { debounce } from 'lodash'; +import { AppContext } from 'src/context'; import { SimpleModal } from '../Modals/SimpleModal'; import { ModalListItem } from '../Modals/ModalListItem'; import { checkTokenBalance, validateAmount, validateKey } from '../../utils'; @@ -15,6 +16,7 @@ import { ConfirmTx } from '../ConfirmTX'; import { getMixnodeStakeSaturation } from '../../requests'; import { ErrorModal } from '../Modals/ErrorModal'; +import { BalanceWarning } from '../FeeWarning'; const MIN_AMOUNT_TO_DELEGATE = 10; @@ -73,6 +75,7 @@ export const DelegateModal: FCWithChildren<{ const [mixIdError, setMixIdError] = useState(); const { fee, getFee, resetFeeState, feeError } = useGetFee(); + const { userBalance } = useContext(AppContext); const handleCheckStakeSaturation = async (newMixId: number) => { try { @@ -213,6 +216,11 @@ export const DelegateModal: FCWithChildren<{ onPrev={resetFeeState} onConfirm={handleOk} > + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + + )} diff --git a/nym-wallet/src/components/Delegation/UndelegateModal.tsx b/nym-wallet/src/components/Delegation/UndelegateModal.tsx index 12662ef3d5..607ee7afdb 100644 --- a/nym-wallet/src/components/Delegation/UndelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/UndelegateModal.tsx @@ -1,5 +1,5 @@ -import { Box, SxProps } from '@mui/material'; import React, { useContext, useEffect } from 'react'; +import { Box, SxProps } from '@mui/material'; import { FeeDetails } from '@nymproject/types'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateUndelegateFromMixnode, simulateVestingUndelegateFromMixnode } from 'src/requests'; diff --git a/nym-wallet/src/components/FeeWarning.tsx b/nym-wallet/src/components/FeeWarning.tsx index 8f22a07591..444b8228dd 100644 --- a/nym-wallet/src/components/FeeWarning.tsx +++ b/nym-wallet/src/components/FeeWarning.tsx @@ -24,7 +24,7 @@ export const BalanceWarning = ({ balance, fee }: { balance: string; fee: string return ( }> Warning: Fees are greater than your balance - The fess are greater than your current balance which cause this transaction to fail. + The fess are greater than your current balance which could cause this transaction to fail. Do you want to continue? ); diff --git a/nym-wallet/src/hooks/useGetBalance.ts b/nym-wallet/src/hooks/useGetBalance.ts index 240910e493..d43eeb1c04 100644 --- a/nym-wallet/src/hooks/useGetBalance.ts +++ b/nym-wallet/src/hooks/useGetBalance.ts @@ -1,5 +1,4 @@ import { useCallback, useEffect, useState } from 'react'; -import { invoke } from '@tauri-apps/api'; import { Account, Balance, DecCoin, OriginalVestingResponse, Period, VestingAccountInfo } from '@nymproject/types'; import { getVestingCoins, @@ -11,6 +10,7 @@ import { getVestingAccountInfo, getSpendableRewardCoins, getSpendableVestedCoins, + userBalance, } from '../requests'; import { Console } from '../utils/console'; @@ -101,8 +101,8 @@ export const useGetBalance = (clientDetails?: Account): TUseuserBalance => { setIsLoading(true); setError(undefined); try { - const bal = await invoke('get_balance'); - setBalance(bal as Balance); + const bal = await userBalance(); + setBalance(bal); } catch (err) { setError(err as string); } finally { diff --git a/nym-wallet/src/utils/generalUtils.ts b/nym-wallet/src/utils/common.ts similarity index 100% rename from nym-wallet/src/utils/generalUtils.ts rename to nym-wallet/src/utils/common.ts diff --git a/nym-wallet/src/utils/index.ts b/nym-wallet/src/utils/index.ts index e0e8ee8101..b1a2ade95a 100644 --- a/nym-wallet/src/utils/index.ts +++ b/nym-wallet/src/utils/index.ts @@ -1,4 +1,4 @@ -export * from './generalUtils'; +export * from './common'; export * from './fireRequests'; export * from './console'; export { default as fireRequests } from './fireRequests'; From 96c29b974b0156b6892ce40e4231374b40231944 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Mon, 26 Jun 2023 17:08:52 +0100 Subject: [PATCH 33/59] add warning for more txs --- .../src/components/Send/SendDetailsModal.tsx | 80 +++++++++++-------- .../GeneralGatewaySettings.tsx | 13 ++- .../GeneralMixnodeSettings.tsx | 15 +++- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/nym-wallet/src/components/Send/SendDetailsModal.tsx b/nym-wallet/src/components/Send/SendDetailsModal.tsx index 366bf7ba9c..b31f5bd4a0 100644 --- a/nym-wallet/src/components/Send/SendDetailsModal.tsx +++ b/nym-wallet/src/components/Send/SendDetailsModal.tsx @@ -1,9 +1,11 @@ -import React from 'react'; -import { Stack, SxProps } from '@mui/material'; +import React, { useContext } from 'react'; +import { Box, Stack, SxProps } from '@mui/material'; import { FeeDetails, DecCoin, CurrencyDenom } from '@nymproject/types'; +import { AppContext } from 'src/context'; import { SimpleModal } from '../Modals/SimpleModal'; import { ModalListItem } from '../Modals/ModalListItem'; import { ModalFee, ModalTotalAmount } from '../Modals/ModalFee'; +import { BalanceWarning } from '../FeeWarning'; export const SendDetailsModal = ({ amount, @@ -29,37 +31,45 @@ export const SendDetailsModal = ({ sx?: SxProps; backdropProps?: object; memo?: string; -}) => ( - amount && onSend({ val: amount, to: toAddress })} - onBack={onPrev} - sx={sx} - backdropProps={backdropProps} - > - - - - - - {memo && ( - +}) => { + const { userBalance } = useContext(AppContext); + return ( + amount && onSend({ val: amount, to: toAddress })} + onBack={onPrev} + sx={sx} + backdropProps={backdropProps} + > + + + + + + {memo && ( + + )} + + + {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + + + )} - - - -); + + ); +}; diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx index f024fcc149..8c1b3849a0 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; import { clean } from 'semver'; import { yupResolver } from '@hookform/resolvers/yup'; @@ -18,11 +18,14 @@ import { ConfirmTx } from 'src/components/ConfirmTX'; import { useGetFee } from 'src/hooks/useGetFee'; import { LoadingModal } from 'src/components/Modals/LoadingModal'; import { updateGatewayValidationSchema } from 'src/components/Bonding/forms/gatewayValidationSchema'; +import { BalanceWarning } from 'src/components/FeeWarning'; +import { AppContext } from 'src/context'; export const GeneralGatewaySettings = ({ bondedNode }: { bondedNode: TBondedGateway }) => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const { getFee, fee, resetFeeState } = useGetFee(); const { refresh } = useBondingContext(); + const { userBalance } = useContext(AppContext); const theme = useTheme(); @@ -78,7 +81,13 @@ export const GeneralGatewaySettings = ({ bondedNode }: { bondedNode: TBondedGate onConfirm={handleSubmit((d) => onSubmit(d))} onPrev={resetFeeState} onClose={resetFeeState} - /> + > + {fee.amount?.amount && userBalance?.balance?.amount.amount && ( + + + + )} + )} {isSubmitting && } { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const { getFee, fee, resetFeeState } = useGetFee(); + const { userBalance } = useContext(AppContext); const theme = useTheme(); @@ -72,7 +75,13 @@ export const GeneralMixnodeSettings = ({ bondedNode }: { bondedNode: TBondedMixn onConfirm={handleSubmit((d) => onSubmit(d))} onPrev={resetFeeState} onClose={resetFeeState} - /> + > + {fee.amount?.amount && userBalance?.balance?.amount.amount && ( + + + + )} + )} {isSubmitting && } Date: Wed, 28 Jun 2023 12:20:47 +0100 Subject: [PATCH 34/59] include tx amount when checking balance --- .../Bonding/modals/BondGatewayModal.tsx | 8 +++++++- .../Bonding/modals/BondMixnodeModal.tsx | 8 +++++++- .../Bonding/modals/RedeemRewardsModal.tsx | 2 +- .../Bonding/modals/UpdateBondAmountModal.tsx | 2 +- .../src/components/Delegation/DelegateModal.tsx | 2 +- .../components/Delegation/UndelegateModal.tsx | 2 +- .../src/components/FeeWarning.stories.tsx | 7 ------- nym-wallet/src/components/FeeWarning.tsx | 16 ++++++++++------ .../src/components/Rewards/RedeemModal.tsx | 2 +- .../src/components/Send/SendDetailsModal.tsx | 2 +- .../general-settings/GeneralGatewaySettings.tsx | 2 +- .../general-settings/GeneralMixnodeSettings.tsx | 2 +- nym-wallet/src/utils/common.ts | 17 +++++++++++------ 13 files changed, 43 insertions(+), 29 deletions(-) diff --git a/nym-wallet/src/components/Bonding/modals/BondGatewayModal.tsx b/nym-wallet/src/components/Bonding/modals/BondGatewayModal.tsx index 0a3cd718a5..defdac3f95 100644 --- a/nym-wallet/src/components/Bonding/modals/BondGatewayModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/BondGatewayModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Box } from '@mui/material'; import { CurrencyDenom, TNodeType } from '@nymproject/types'; import { ConfirmTx } from 'src/components/ConfirmTX'; @@ -9,6 +9,8 @@ import { useGetFee } from 'src/hooks/useGetFee'; import { GatewayAmount, GatewayData, Signature } from 'src/pages/bonding/types'; import { simulateBondGateway, simulateVestingBondGateway } from 'src/requests'; import { TBondGatewayArgs } from 'src/types'; +import { BalanceWarning } from 'src/components/FeeWarning'; +import { AppContext } from 'src/context'; import { BondGatewayForm } from '../forms/BondGatewayForm'; import { gatewayToTauri } from '../utils'; @@ -50,6 +52,7 @@ export const BondGatewayModal = ({ const [signature, setSignature] = useState(); const { fee, getFee, resetFeeState, feeError } = useGetFee(); + const { userBalance } = useContext(AppContext); useEffect(() => { if (feeError) { @@ -123,6 +126,9 @@ export const BondGatewayModal = ({ value={`${amountData.amount.amount} ${amountData.amount.denom.toUpperCase()}`} divider /> + {fee.amount?.amount && userBalance.balance && ( + + )} ); } diff --git a/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx b/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx index 6cad10f9ab..4e4c39f9cf 100644 --- a/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { CurrencyDenom, TNodeType } from '@nymproject/types'; import { ConfirmTx } from 'src/components/ConfirmTX'; import { ModalListItem } from 'src/components/Modals/ModalListItem'; @@ -8,6 +8,8 @@ import { useGetFee } from 'src/hooks/useGetFee'; import { MixnodeAmount, MixnodeData, Signature } from 'src/pages/bonding/types'; import { simulateBondMixnode, simulateVestingBondMixnode } from 'src/requests'; import { TBondMixNodeArgs } from 'src/types'; +import { BalanceWarning } from 'src/components/FeeWarning'; +import { AppContext } from 'src/context'; import { BondMixnodeForm } from '../forms/BondMixnodeForm'; import { costParamsToTauri, mixnodeToTauri } from '../utils'; @@ -50,6 +52,7 @@ export const BondMixnodeModal = ({ const [signature, setSignature] = useState(); const { fee, getFee, resetFeeState, feeError } = useGetFee(); + const { userBalance } = useContext(AppContext); useEffect(() => { if (feeError) { @@ -125,6 +128,9 @@ export const BondMixnodeModal = ({ value={`${amountData.amount.amount} ${amountData.amount.denom.toUpperCase()}`} divider /> + {fee.amount?.amount && userBalance.balance && ( + + )} ); } diff --git a/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx b/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx index 88490e7e0e..ba802967d8 100644 --- a/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/RedeemRewardsModal.tsx @@ -56,7 +56,7 @@ export const RedeemRewardsModal = ({ {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx b/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx index 07be4bcf47..2148313b70 100644 --- a/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/UpdateBondAmountModal.tsx @@ -107,7 +107,7 @@ export const UpdateBondAmountModal = ({ {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/components/Delegation/DelegateModal.tsx b/nym-wallet/src/components/Delegation/DelegateModal.tsx index 12d076f7c8..211b4ae2b9 100644 --- a/nym-wallet/src/components/Delegation/DelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/DelegateModal.tsx @@ -218,7 +218,7 @@ export const DelegateModal: FCWithChildren<{ > {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/components/Delegation/UndelegateModal.tsx b/nym-wallet/src/components/Delegation/UndelegateModal.tsx index 607ee7afdb..65820eb2bb 100644 --- a/nym-wallet/src/components/Delegation/UndelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/UndelegateModal.tsx @@ -55,7 +55,7 @@ export const UndelegateModal: FCWithChildren<{ {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/components/FeeWarning.stories.tsx b/nym-wallet/src/components/FeeWarning.stories.tsx index 9202ecc300..7a553aae79 100644 --- a/nym-wallet/src/components/FeeWarning.stories.tsx +++ b/nym-wallet/src/components/FeeWarning.stories.tsx @@ -16,12 +16,5 @@ const Template: ComponentStory = (args) => ( export const WithWarning = Template.bind({}); WithWarning.args = { - balance: '100', fee: '200', }; - -export const NoWarning = Template.bind({}); -NoWarning.args = { - balance: '100', - fee: '100', -}; diff --git a/nym-wallet/src/components/FeeWarning.tsx b/nym-wallet/src/components/FeeWarning.tsx index 444b8228dd..745353b2c6 100644 --- a/nym-wallet/src/components/FeeWarning.tsx +++ b/nym-wallet/src/components/FeeWarning.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { Warning } from '@mui/icons-material'; import { FeeDetails } from '@nymproject/types'; import { Alert, AlertTitle, Box } from '@mui/material'; import { isBalanceEnough } from 'src/utils'; +import { AppContext } from 'src/context'; export const FeeWarning = ({ fee, amount }: { fee: FeeDetails; amount: number }) => { if (fee.amount && +fee.amount.amount > amount) { @@ -16,15 +17,18 @@ export const FeeWarning = ({ fee, amount }: { fee: FeeDetails; amount: number }) return null; }; -export const BalanceWarning = ({ balance, fee }: { balance: string; fee: string }) => { - const hasEnoughBalanace = isBalanceEnough(balance, fee); +export const BalanceWarning = ({ tx, fee }: { fee: string; tx?: string }) => { + const { userBalance } = useContext(AppContext); - if (!balance || !fee || hasEnoughBalanace) return null; + const hasEnoughBalanace = isBalanceEnough(fee, tx, userBalance.balance?.amount.amount); + + if (hasEnoughBalanace) return null; return ( }> - Warning: Fees are greater than your balance - The fess are greater than your current balance which could cause this transaction to fail. + Warning: Transaction amount is greater than your balance + The transaction amount (inc fees) is greater than your current balance, which could cause this transaction to + fail. Do you want to continue? ); diff --git a/nym-wallet/src/components/Rewards/RedeemModal.tsx b/nym-wallet/src/components/Rewards/RedeemModal.tsx index ec6bde1846..b9c774cb2e 100644 --- a/nym-wallet/src/components/Rewards/RedeemModal.tsx +++ b/nym-wallet/src/components/Rewards/RedeemModal.tsx @@ -60,7 +60,7 @@ export const RedeemModal: FCWithChildren<{ {fee && } {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/components/Send/SendDetailsModal.tsx b/nym-wallet/src/components/Send/SendDetailsModal.tsx index b31f5bd4a0..061345c68b 100644 --- a/nym-wallet/src/components/Send/SendDetailsModal.tsx +++ b/nym-wallet/src/components/Send/SendDetailsModal.tsx @@ -67,7 +67,7 @@ export const SendDetailsModal = ({ {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - + )} diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx index 8c1b3849a0..892c1e245c 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralGatewaySettings.tsx @@ -84,7 +84,7 @@ export const GeneralGatewaySettings = ({ bondedNode }: { bondedNode: TBondedGate > {fee.amount?.amount && userBalance?.balance?.amount.amount && ( - + )} diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralMixnodeSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralMixnodeSettings.tsx index 1523612195..509c605174 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralMixnodeSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/GeneralMixnodeSettings.tsx @@ -78,7 +78,7 @@ export const GeneralMixnodeSettings = ({ bondedNode }: { bondedNode: TBondedMixn > {fee.amount?.amount && userBalance?.balance?.amount.amount && ( - + )} diff --git a/nym-wallet/src/utils/common.ts b/nym-wallet/src/utils/common.ts index 39366fa724..f4ddba7275 100644 --- a/nym-wallet/src/utils/common.ts +++ b/nym-wallet/src/utils/common.ts @@ -210,16 +210,21 @@ export const unymToNym = (unym: string | Big, dp = 4) => { /** * * Checks if the user's balance is enough to pay the fee - * @param balance - The user's balance to check - * @param fee - The fee to check + * @param balance - The user's current balance + * @param fee - The fee for the tx + * @param tx - The amount of the tx * @returns boolean * */ -export const isBalanceEnough = (balance: string, fee: string) => { - if (!fee || !userBalance) return false; - if (!balance) return false; - return Number(balance) >= Number(fee); +export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => { + console.log('balance', balance, fee, tx); + try { + return Big(balance).gte(Big(fee).plus(Big(tx))); + } catch (e) { + console.log(e); + return false; + } }; export const getIntervalAsDate = async () => { From 867b745a38f2fb04948376263dc988d2caca9491 Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 25 Jul 2023 08:53:25 +0200 Subject: [PATCH 35/59] fix(nc-android): http requests --- nym-connect/native/android/app/build.gradle | 4 +-- .../java/net/nymtech/nyms5/ProxyWorker.kt | 34 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/nym-connect/native/android/app/build.gradle b/nym-connect/native/android/app/build.gradle index 5cd2701c53..72ba890287 100644 --- a/nym-connect/native/android/app/build.gradle +++ b/nym-connect/native/android/app/build.gradle @@ -2,7 +2,7 @@ plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.21' - id "io.sentry.android.gradle" version "3.11.0" + id 'io.sentry.android.gradle' version '3.11.0' } android { @@ -122,6 +122,6 @@ dependencies { androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' - implementation 'com.github.kittinunf.fuel:fuel:3.0.0-alpha1' + implementation 'com.github.kittinunf.fuel:fuel:2.3.1' implementation 'io.sentry:sentry-android:6.24.0' } diff --git a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ProxyWorker.kt b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ProxyWorker.kt index c2f71c3118..6f798eff9a 100644 --- a/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ProxyWorker.kt +++ b/nym-connect/native/android/app/src/main/java/net/nymtech/nyms5/ProxyWorker.kt @@ -15,8 +15,7 @@ import androidx.work.ForegroundInfo import androidx.work.WorkManager import androidx.work.WorkerParameters import androidx.work.workDataOf -import fuel.Fuel -import fuel.get +import com.github.kittinunf.fuel.Fuel import io.sentry.Sentry import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString @@ -110,20 +109,23 @@ class ProxyWorker( var serviceProvider: String? = null // fetch the SP list and select a random one try { - val res = Fuel.get(spUrl) - if (res.statusCode == 200) { - val spJson = json.decodeFromString(res.body) - serviceProvider = - Random.nextInt(until = spJson.items.size) - .let { spJson.items[it].service_provider_client_id } - Log.d(tag, "selected service provider: $serviceProvider") - } else { - Log.w( - tag, - "failed to fetch the service providers list: $res.statusCode" - ) - Log.w(tag, "using a default service provider $defaultSp") - } + val (_, response, result) = Fuel.get(spUrl).responseString() + result.fold( + { data -> + val spJson = json.decodeFromString(data) + serviceProvider = + Random.nextInt(until = spJson.items.size) + .let { spJson.items[it].service_provider_client_id } + Log.d(tag, "selected service provider: $serviceProvider") + }, + { error -> + Log.w( + tag, + "failed to fetch the service provider list: ${response.statusCode} ${error.message}" + ) + Log.w(tag, "using a default service provider $defaultSp") + } + ) } catch (e: Throwable) { Log.e( tag, From 524863aae7144633d012e182f1e907879bd61d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Tue, 25 Jul 2023 13:51:27 +0200 Subject: [PATCH 36/59] Uncouple gateways and network-requester in nym-connect (#3639) * Split fetching network-requesters from gateways * Tidy names * Select gateway independenty in frontend * Fix threshold value * Fix gateway type * Fix naming for setGateway and setServiceProvider * Unshadow variable * Naming conventions * Missing semicolon * Explicit types in invoke calls * Dedup random function * Inline some functions * Silence handlebars in log * Emojis in healthcheck log statements * Remove gateway from service provider type * Remove unneeded type cast * fix linting * Remove gateway field from harbour master response type --------- Co-authored-by: fmtabbara --- nym-connect/desktop/src-tauri/src/logging.rs | 15 +- nym-connect/desktop/src-tauri/src/main.rs | 3 +- .../desktop/src-tauri/src/models/mod.rs | 11 +- .../src/operations/connection/health_check.rs | 6 +- .../src-tauri/src/operations/directory/mod.rs | 161 +++++---- .../src/components/ConnectionStatus.tsx | 17 +- .../ServiceProviderSelector.stories.tsx | 342 ------------------ .../components/ServiceProviderSelector.tsx | 147 -------- .../components/ServiceSelector.stories.tsx | 342 ------------------ .../src/components/ServiceSelector.tsx | 179 --------- .../desktop/src/components/TooltipInfo.tsx | 12 +- nym-connect/desktop/src/context/main.tsx | 67 ++-- .../desktop/src/context/mocks/main.tsx | 5 +- .../src/pages/connection/Connected.tsx | 5 +- .../desktop/src/pages/connection/index.tsx | 4 +- .../desktop/src/stories/AppFlow.stories.tsx | 1 - .../src/stories/ConnectedLayout.stories.tsx | 2 +- .../src/stories/DefaultLayout.stories.tsx | 2 +- nym-connect/desktop/src/types/directory.ts | 5 +- 19 files changed, 190 insertions(+), 1136 deletions(-) delete mode 100644 nym-connect/desktop/src/components/ServiceProviderSelector.stories.tsx delete mode 100644 nym-connect/desktop/src/components/ServiceProviderSelector.tsx delete mode 100644 nym-connect/desktop/src/components/ServiceSelector.stories.tsx delete mode 100644 nym-connect/desktop/src/components/ServiceSelector.tsx diff --git a/nym-connect/desktop/src-tauri/src/logging.rs b/nym-connect/desktop/src-tauri/src/logging.rs index 497813003d..b1441a5a02 100644 --- a/nym-connect/desktop/src-tauri/src/logging.rs +++ b/nym-connect/desktop/src-tauri/src/logging.rs @@ -104,16 +104,17 @@ impl FernExt for fern::Dispatch { } fn filter_lowlevel_external_components(self) -> Self { - self.level_for("hyper", log::LevelFilter::Warn) - .level_for("tokio_reactor", log::LevelFilter::Warn) - .level_for("reqwest", log::LevelFilter::Warn) + self.level_for("handlebars", log::LevelFilter::Warn) + .level_for("hyper", log::LevelFilter::Warn) .level_for("mio", log::LevelFilter::Warn) - .level_for("want", log::LevelFilter::Warn) - .level_for("sled", log::LevelFilter::Warn) - .level_for("tungstenite", log::LevelFilter::Warn) - .level_for("tokio_tungstenite", log::LevelFilter::Warn) + .level_for("reqwest", log::LevelFilter::Warn) .level_for("rustls", log::LevelFilter::Warn) + .level_for("sled", log::LevelFilter::Warn) + .level_for("tokio_reactor", log::LevelFilter::Warn) + .level_for("tokio_tungstenite", log::LevelFilter::Warn) .level_for("tokio_util", log::LevelFilter::Warn) + .level_for("tungstenite", log::LevelFilter::Warn) + .level_for("want", log::LevelFilter::Warn) } } diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index 02981ee1ee..8449cb3973 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -3,7 +3,6 @@ windows_subsystem = "windows" )] -use std::env; use std::sync::Arc; use nym_config::defaults::setup_env; @@ -83,7 +82,7 @@ fn main() { crate::operations::connection::status::get_gateway_connection_status, crate::operations::connection::status::start_connection_health_check_task, crate::operations::directory::get_services, - crate::operations::directory::get_gateways_detailed, + crate::operations::directory::get_gateways, crate::operations::export::export_keys, crate::operations::window::hide_window, crate::operations::growth::test_and_earn::growth_tne_get_client_id, diff --git a/nym-connect/desktop/src-tauri/src/models/mod.rs b/nym-connect/desktop/src-tauri/src/models/mod.rs index fb43877675..1b9ed11e71 100644 --- a/nym-connect/desktop/src-tauri/src/models/mod.rs +++ b/nym-connect/desktop/src-tauri/src/models/mod.rs @@ -86,7 +86,6 @@ pub struct DirectoryService { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct HarbourMasterService { pub service_provider_client_id: String, - pub gateway_identity_key: String, pub ip_address: String, pub last_successful_ping_utc: String, pub last_updated_utc: String, @@ -98,11 +97,9 @@ pub struct HarbourMasterService { pub struct DirectoryServiceProvider { pub id: String, pub description: String, - /// Address of the network requester in the form "." + /// 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, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -112,3 +109,9 @@ pub struct PagedResult { pub total: i32, pub items: Vec, } + +#[cfg_attr(test, derive(ts_rs::TS))] +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Gateway { + pub identity: String, +} diff --git a/nym-connect/desktop/src-tauri/src/operations/connection/health_check.rs b/nym-connect/desktop/src-tauri/src/operations/connection/health_check.rs index 3f401933a1..52b47057b1 100644 --- a/nym-connect/desktop/src-tauri/src/operations/connection/health_check.rs +++ b/nym-connect/desktop/src-tauri/src/operations/connection/health_check.rs @@ -11,15 +11,15 @@ pub async fn run_health_check() -> bool { log::info!("Running network health check"); match crate::operations::http::socks5_get::<_, ConnectionSuccess>(HEALTH_CHECK_URL).await { Ok(res) if res.status == "ok" => { - log::info!("Healthcheck success!"); + log::info!("✅✅✅ Healthcheck success!"); true } Ok(res) => { - log::error!("Healthcheck failed with status: {}", res.status); + log::error!("⛔⛔⛔ Healthcheck failed with status: {}", res.status); false } Err(err) => { - log::error!("Healthcheck failed: {err}"); + log::error!("⛔⛔⛔ Healthcheck failed: {err}"); false } } diff --git a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs index 0b1d36819f..a4f8bf53a9 100644 --- a/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs +++ b/nym-connect/desktop/src-tauri/src/operations/directory/mod.rs @@ -1,11 +1,12 @@ -use itertools::Itertools; - -use crate::config::PrivacyLevel; -use crate::error::Result; -use crate::models::{ - DirectoryService, DirectoryServiceProvider, HarbourMasterService, PagedResult, +use crate::{ + config::PrivacyLevel, + error::Result, + models::{ + DirectoryService, DirectoryServiceProvider, Gateway, HarbourMasterService, PagedResult, + }, + state::State, }; -use crate::state::State; +use itertools::Itertools; use nym_api_requests::models::GatewayBondAnnotated; use nym_contracts_common::types::Percent; use std::sync::Arc; @@ -18,26 +19,39 @@ static SERVICE_PROVIDER_WELLKNOWN_URL: &str = static SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM: &str = "https://nymtech.net/.wellknown/connect/service-providers-medium.json"; +// Harbour master is used to periodically keep track of which network-requesters are online static HARBOUR_MASTER_URL: &str = "https://harbourmaster.nymtech.net/v1/services/?size=100"; +// We only consider network requesters with a routing score above this threshold +const SERVICE_ROUTING_SCORE_THRESHOLD: f32 = 0.9; + static GATEWAYS_DETAILED_URL: &str = "https://validator.nymtech.net/api/v1/status/gateways/detailed"; +// Only use gateways with a performnnce score above this +const GATEWAY_PERFORMANCE_SCORE_THRESHOLD: u64 = 90; + #[tauri::command] pub async fn get_services( state: tauri::State<'_, Arc>>, ) -> Result> { - log::trace!("Fetching services"); - let guard = state.read().await; let privacy_level = guard.get_user_data().privacy_level.unwrap_or_default(); - let all_services = fetch_services(&privacy_level).await?; - log::trace!("Received: {:#?}", all_services); + log::trace!("Fetching services"); + let all_services_with_category = fetch_services(&privacy_level).await?; + log::trace!("Received: {:#?}", all_services_with_category); + + // Flatten all services into a single vector (get rid of categories) + // We currently don't care about categories, but we might in the future... + let all_services = all_services_with_category + .into_iter() + .flat_map(|sp| sp.items) + .collect_vec(); // Early return if we're running with medium toggle enabled if let PrivacyLevel::Medium = privacy_level { - return Ok(all_services.into_iter().flat_map(|sp| sp.items).collect()); + return Ok(all_services); } // TODO: get paged @@ -45,61 +59,23 @@ pub async fn get_services( let active_services = fetch_active_services().await?; log::trace!("Active: {:#?}", active_services); - let filtered_services = filter_out_inactive(all_services, active_services); - - log::trace!("Fetching gateways"); - let gateway_res = get_gateways_detailed().await?; - log::trace!("Received: {:#?}", gateway_res); - - // Use only services that are active AND have a performance of >= 90% - let filtered_services_with_good_gateway = - filter_out_poor_gateways(filtered_services, gateway_res); - - Ok(filtered_services_with_good_gateway) -} - -fn filter_out_inactive( - services_res: Vec, - active_services: PagedResult, -) -> Vec { - let mut filtered: Vec = vec![]; - for service_type in &services_res { - let items = service_type - .items - .clone() - .into_iter() - .filter(|sp| { - active_services - .items - .iter() - .any(|active| active.service_provider_client_id == sp.address) - }) - .collect_vec(); - log::trace!("service = {} has {} items", service_type.id, items.len()); - filtered.push(DirectoryService { - id: service_type.id.clone(), - description: service_type.description.clone(), - items, - }) + if active_services.items.is_empty() { + log::warn!("No active services found! Using all services instead as fallback"); + return Ok(all_services); } - filtered -} -fn filter_out_poor_gateways( - services: Vec, - gateway_res: Vec, -) -> Vec { - let perf_threshold = Percent::from_percentage_value(90).unwrap(); - services - .into_iter() - .flat_map(|sp| sp.items) - .filter(|sp| { - gateway_res.iter().any(|gateway| { - gateway.gateway_bond.gateway.identity_key == sp.gateway - && gateway.performance >= perf_threshold - }) - }) - .collect() + log::trace!("Filter out inactive"); + let filtered_services = filter_out_inactive_services(&all_services, active_services); + log::trace!("After filtering: {:#?}", filtered_services); + + if filtered_services.is_empty() { + log::warn!( + "After filtering, no active services found! Using all services instead as fallback" + ); + return Ok(all_services); + } + + Ok(filtered_services) } async fn fetch_services(privacy_level: &PrivacyLevel) -> Result> { @@ -123,11 +99,56 @@ async fn fetch_active_services() -> Result> { Ok(active_services) } -#[tauri::command] -pub async fn get_gateways_detailed() -> Result> { - let res = reqwest::get(GATEWAYS_DETAILED_URL) +fn filter_out_inactive_services( + all_services: &[DirectoryServiceProvider], + active_services: PagedResult, +) -> Vec { + all_services + .iter() + .filter(|sp| { + active_services.items.iter().any(|active| { + active.service_provider_client_id == sp.address + && active.routing_score > SERVICE_ROUTING_SCORE_THRESHOLD + }) + }) + .cloned() + .collect() +} + +async fn fetch_gateways() -> Result> { + Ok(reqwest::get(GATEWAYS_DETAILED_URL) .await? .json::>() - .await?; - Ok(res) + .await?) +} + +#[tauri::command] +pub async fn get_gateways() -> Result> { + log::trace!("Fetching gateways"); + let all_gateways = fetch_gateways().await?; + log::trace!("Received: {:#?}", all_gateways); + + let filtered_gateways = all_gateways + .iter() + .filter(|g| { + g.node_performance.most_recent + > Percent::from_percentage_value(GATEWAY_PERFORMANCE_SCORE_THRESHOLD).unwrap() + }) + .map(|g| Gateway { + identity: g.identity().clone(), + }) + .collect_vec(); + log::trace!("Filtered: {:#?}", filtered_gateways); + + if filtered_gateways.is_empty() { + log::warn!("No gateways with high enough performance score found! Using all gateways instead as fallback"); + return Ok(all_gateways + .iter() + .map(|g| Gateway { + identity: g.identity().clone(), + }) + .collect_vec()); + } + + Ok(filtered_gateways) } diff --git a/nym-connect/desktop/src/components/ConnectionStatus.tsx b/nym-connect/desktop/src/components/ConnectionStatus.tsx index 73fb6bf992..1a09c8b18e 100644 --- a/nym-connect/desktop/src/components/ConnectionStatus.tsx +++ b/nym-connect/desktop/src/components/ConnectionStatus.tsx @@ -3,7 +3,7 @@ import { Box, CircularProgress, Stack, Tooltip, Typography } from '@mui/material import { DateTime } from 'luxon'; import { ErrorOutline, InfoOutlined } from '@mui/icons-material'; import { ConnectionStatusKind, GatewayPerformance } from '../types'; -import { ServiceProvider } from '../types/directory'; +import { ServiceProvider, Gateway } from '../types/directory'; import { GatwayWarningInfo, ServiceProviderInfo } from './TooltipInfo'; import { useClientContext } from '../context/main'; @@ -14,8 +14,9 @@ const FONT_STYLE = 'normal'; const ConnectionStatusContent: FCWithChildren<{ status: ConnectionStatusKind; serviceProvider?: ServiceProvider; + gateway?: Gateway; gatewayError: boolean; -}> = ({ status, serviceProvider, gatewayError }) => { +}> = ({ status, serviceProvider, gateway, gatewayError }) => { const { userData } = useClientContext(); if (gatewayError) { @@ -41,7 +42,13 @@ const ConnectionStatusContent: FCWithChildren<{ case 'connected': return ( <> - : undefined}> + + ) : undefined + } + > @@ -93,7 +100,8 @@ export const ConnectionStatus: FCWithChildren<{ gatewayPerformance?: GatewayPerformance; connectedSince?: DateTime; serviceProvider?: ServiceProvider; -}> = ({ status, serviceProvider, gatewayPerformance }) => { + gateway?: Gateway; +}> = ({ status, serviceProvider, gateway, gatewayPerformance }) => { const color = status === 'connected' || status === 'disconnecting' ? '#21D072' : 'white'; return ( @@ -101,6 +109,7 @@ export const ConnectionStatus: FCWithChildren<{ diff --git a/nym-connect/desktop/src/components/ServiceProviderSelector.stories.tsx b/nym-connect/desktop/src/components/ServiceProviderSelector.stories.tsx deleted file mode 100644 index c7df76ea4a..0000000000 --- a/nym-connect/desktop/src/components/ServiceProviderSelector.stories.tsx +++ /dev/null @@ -1,342 +0,0 @@ -import * as React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Box } from '@mui/material'; -import { ServiceProviderSelector } from './ServiceProviderSelector'; -import { Services } from '../types/directory'; - -export default { - title: 'Components/Service Provider Selector', - component: ServiceProviderSelector, -} as ComponentMeta; - -const width = 240; - -export const Loading = () => ( - - - -); - -const services: Services = JSON.parse(`[ - { - "id": "keybase", - "description": "Keybase", - "items": [ - { - "id": "nym-keybase", - "description": "Nym Keybase Service Provider", - "address": "Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf", - "gateway": "Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf" - }, - { - "id": "shipyard-keybase-1", - "description": "Nym Keybase Service Provider", - "address": "D55ksecHzY6vAeqk8MCTzCfj2pqwJeKCKZCUUGnwGnn3.FS42vXS5a6GNTb1qk3aVk5mjSiJCAuawbBVyQZZVfhvt@DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn", - "gateway": "DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn" - }, - { - "id": "shipyard-keybase-2", - "description": "Nym Keybase Service Provider", - "address": "DFdDtW7LNBATxQ4ef3jNbqs3cRE8b9wDZTCctHCQRULa.4AbKiTNVUwYFWHhy98o5pT9dELiUrkXoJQ9wHqPgf6GV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN", - "gateway": "GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN" - }, - { - "id": "shipyard-keybase-3", - "description": "Nym Keybase Service Provider", - "address": "6Y1HE1jJ92P9yoHer11TR4A2NdZePrLGaBNFf65MnYGe.FwXoh217odQDWNmViqzNX28fauYrjB3PYLrVvpqnQrX4@5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz", - "gateway": "5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz" - }, - { - "id": "shipyard-keybase-4", - "description": "Nym Keybase Service Provider", - "address": "3zzhLtWvaJgn755MkRckG5aRnoTZich8ASn395iSsTgj.J1R5VuxXbh2eNHiaRbrwbKGXrrEQcHKLdzf8eg9HTB6q@3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj", - "gateway": "3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj" - }, - { - "id": "shipyard-keybase-5", - "description": "Nym Keybase Service Provider", - "address": "CHuXdZJYQ8xH7ekgN9gAuVtQ7ZikjjHEZY5BSN7yc5mN.29dFvqicKQQQvoX1vup44mspmc249RH5xgLibWMwTYGT@CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9", - "gateway": "CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9" - } - ] - }, - { - "id": "electrum", - "description": "Electrum Wallet", - "items": [ - { - "id": "nym-electrum", - "description": "Nym Electrum Service Provider", - "address": "DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh", - "gateway": "2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh" - }, - { - "id": "shipyard-electrum-1", - "description": "Nym Electrum Service Provider", - "address": "8Tb73cFQpXCLpgxEA2VSDru2hHrcZ3KQcyMsGbxcTjBp.4x5tu66k8YkHk4tYac1qwEFbNq5WsKiX5kR51q5KKH88@4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd", - "gateway": "4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd" - }, - { - "id": "shipyard-electrum-2", - "description": "Nym Electrum Service Provider", - "address": "GR6z31MwCsvxHrnvvVN1Cpasd8aQ1giwQqPTZM9dN7VH.5rEiqakSPDrBtKmvpU8Shnhz6gRM85JLoB7AX4h7PJYr@5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD", - "gateway": "5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD" - } - ] - }, - { - "id": "telegram", - "description": "Telegram", - "items": [ - { - "id": "shipyard-telegram-2", - "description": "Nym Telegram Service Provider", - "address": "C4w6ewbQtoaZEeoaaNw1xVASChqo4WVjNfuYEUFjZxpc.8F1D7rQXf2jGoj1Ken7PiGDM8HS2Ug79wSoc9nZ1iqh1@62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve", - "gateway": "62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve" - }, - { - "id": "shipyard-telegram-3", - "description": "Nym Telegram Service Provider", - "address": "DStL3BEUZuQZfbij1KAY3BvJh8rC5jpr9mc6AQ6aTLUu.Ax9foYaKfFgX6g8y393GoNpKkKrnDGFGRZwxDv9R7X6M@FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE", - "gateway": "FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE" - }, - { - "id": "shipyard-telegram-4", - "description": "Nym Telegram Service Provider", - "address": "8gRdGTzsDxYzpasRQhsRg59MCgNNhnfag2oFfwwZPXnB.DtDrGz7ScVm4o7sN4K3CYUJveYgz7fcXELBVLNDfMS9Y@3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh", - "gateway": "3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh" - }, - { - "id": "shipyard-telegram-5", - "description": "Nym Telegram Service Provider", - "address": "AR3oEM6Uvmfs6fyddwSehoBUKCFxz7MdFi4z7aahuHuY.3ZKapg9A3Py1PXhyLbCJr8ZbJsEV6NZdN1WJaGGut5tj@EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp", - "gateway": "EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp" - }, - { - "id": "shipyard-telegram-6", - "description": "Nym Telegram Service Provider", - "address": "7n1BYhsXSwcr8Qim8AqZTAodqFia4QG6T7CRc1ihQHpv.7o4trpGqu2LHMUiXc3dddgfGET1CFFcAK9gKYoHoSn5e@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr", - "gateway": "BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr" - }, - { - "id": "shipyard-telegram-7", - "description": "Nym Telegram Service Provider", - "address": "Gv4TWhUKrvJfqh1jBRPGEQrikNZvZse2kS3ZgN9Z2nAZ.7KGPaaqUEum2C59jLvw7f8Ug8a48YuZdjjZu3t4JES4U@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", - "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" - }, - { - "id": "shipyard-telegram-8", - "description": "Nym Telegram Service Provider", - "address": "8Mqgp12cpF6FSXMeqzxgFgQXvTSapyNqGAi5wy7ub4ge.7z7PDsiJGiGxGz4p77v5L5fZhXBJ5qNZ8CgJwYNr6H6J", - "gateway": "3zd3wrCK8Dz5TXrcvk5dG5s9EEdf4Ck1v9VgBPMMFVkR" - }, - { - "id": "shipyard-telegram-9", - "description": "Nym Telegram Service Provider", - "address": "F3N5eiPDZcGFC985Go4Mpv8p9uxFD1L3jRUdrLCbrZLm.EyTxWwwTwYpPrJBmc97GLd1LpUAphjptS5y1ed182bGk@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", - "gateway": "GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" - }, - { - "id": "shipyard-telegram-10", - "description": "Nym Telegram Service Provider", - "address": "G7y7e1nVBr8fmQSzdeAxXnCmmmJb5k8N3E8LBV31KE5g.GRRUCj6t6cCUUjakmTWzidMLiYA7EdCedKnup8osaBC6@AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc", - "gateway": "AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc" - }, - { - "id": "shipyard-telegram-11", - "description": "Nym Telegram Service Provider", - "address": "2kq9Z7RyDZtb8kxXjyP3ZT8VMWHg6JXFDChGuuNBk7Hw.F5XYbBaGSoF8qAo8faPcaNRPHEq3Y25BDcwESeabUS9S@HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM", - "gateway": "HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM" - }, - { - "id": "shipyard-telegram-12", - "description": "Nym Telegram Service Provider", - "address": "GegdtpNzYj4QCgpih9Kxv7ZVZxmVdxYHsDkiPsbT71XG.E8xtE8mrapjzFtyuziZSrsScAKhwZMH5wNpKWtKfzJ5Y@9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J", - "gateway": "9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J" - }, - { - "id": "shipyard-telegram-13", - "description": "Nym Telegram Service Provider", - "address": "4SsrDQeEtG3mpeD9nN5CDdGaCsxFvNeYMhoviDzNNB9f.GyqG6iK5rBvhe3HXLR11m6ULpf13ATgYvkkidLmteDLs@5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS", - "gateway": "5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS" - }, - { - "id": "shipyard-telegram-14", - "description": "Nym Telegram Service Provider", - "address": "9JoHRu2RrSD1fjbj9NSTASgjv9Szep7Nhd9L2PywxbBi.AZhAUDNX6iH8BqXyR5c7TJuzpwMEvDXrabNLGuRukvVf@9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS", - "gateway": "9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS" - }, - { - "id": "shipyard-telegram-15", - "description": "Nym Telegram Service Provider", - "address": "3K174ijjXqCkhMDT9xLcqjS4MXk2QsqZt4PdgNcuUrnn.BNnHnQmWoj6Uo6kkS1QkPqsdHaXrcwyR9F6MnnzDkZJL@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", - "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" - }, - { - "id": "shipyard-telegram-16", - "description": "Nym Telegram Service Provider", - "address": "BqX5Q3MEcbTnM39hUswQchLW68SrqbhL8K5ucrLmtP39.AWrVsFoVC9s6KjdpcasATmZPA3GtMsUxcfHpAkuNdtFG@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS", - "gateway": "Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS" - }, - { - "id": "shipyard-telegram-17", - "description": "Nym Telegram Service Provider", - "address": "2tQxccgcqdkuUvLqgiEkEN4rNRZ5QknygnKAFcS4gfoe.EVrY5q5sqDqBUbS3wHsRRZhk2MAw1S17hNoH1Bicyv7n@DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom", - "gateway": "DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom" - }, - { - "id": "shipyard-telegram-18", - "description": "Nym Telegram Service Provider", - "address": "8YG1rcEauJA814Nd7hSxjNe2UrRwrGsrXTm1Cmd3gRrU.FxYaYqpNN8PciNsySs3zYPrTB1J8AYUu9DBsM2vVDDfF@7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog", - "gateway": "7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog" - }, - { - "id": "shipyard-telegram-19", - "description": "Nym Telegram Service Provider", - "address": "HPiXADVFLwLQPNpPtyYefzvYntC6tp9UJ5fJZGfkqvDt.2EUUxmeT3AiaUzAcE5SyXRAk8a2JXBkRz4B8McSdkrST@9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD", - "gateway": "9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD" - }, - { - "id": "shipyard-telegram-20", - "description": "Nym Telegram Service Provider", - "address": "2QLnEEnTmf2NRWtcQPWBeRcg7Hej5WSPWRWwtTpEEZWF.BheS78ozc8ngvhsXNNnshdJzpoYsmEvhfn3WKUYF5dRU@C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF", - "gateway": "C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF" - }, - { - "id": "shipyard-telegram-21", - "description": "Nym Telegram Service Provider", - "address": "FuBbnwiANfaXZnn683jBapK5XVm5ttgZSykU3vqPSHoD.94MFGv1VcBLTkRwzBDQUkWjvqtZYVBrJg2Q8JGbizcib@CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK", - "gateway": "CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK" - }, - { - "id": "shipyard-telegram-22", - "description": "Nym Telegram Service Provider", - "address": "9EbQx5jQznSVbftFom7sqUSHAACrsfvMhrzhaFt4A3SZ.D1FQCirL4YKwfcmtMGvB5Rugt5sAzGEhdSjJ3bHVQRZ@7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4", - "gateway": "7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4" - }, - { - "id": "shipyard-telegram-24", - "description": "Nym Telegram Service Provider", - "address": "6Umawwvf551VyB3Ko46NgKLqJdTFJeToCM67mrTmM3G.3A4sesBac4KGuMTFjvYBwLpksMJvbMbteGJQgmm4PV4Y@AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR", - "gateway": "AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR" - }, - { - "id": "shipyard-telegram-25", - "description": "Nym Telegram Service Provider", - "address": "CDtxTeoyqq83JpV9G8cR5HRHRdMMaVspQsCwH3Qnajt3.F5EHK9HFcdGrE2hqA7bK9AUmkbihujYDhtNNqHKxW765@BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH", - "gateway": "BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH" - }, - { - "id": "shipyard-telegram-26", - "description": "Nym Telegram Service Provider", - "address": "HukZkLG2DoarQEqaoDLuqW1GFf2NSHDUMGBZiyJGRYJD.9GyU8wPsyzcvRjcyk8hiNpTJbXCmq5F3VoVhFBZYuHR3@GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN", - "gateway": "GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN" - }, - { - "id": "shipyard-telegram-27", - "description": "Nym Telegram Service Provider", - "address": "773y8iMVJiRk4dRbjQzkJVbrei4TwkePNE5WTEttt77d.3Mw47C9XZj3oAzk1iSqC5Y36tbBsjtaTtdgaHM3Zsdma@7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv", - "gateway": "7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv" - }, - { - "id": "shipyard-telegram-28", - "description": "Nym Telegram Service Provider", - "address": "6jQJEorCu7YiP9HdDaMeHxcNhxeNmZ1kpd836GnqLZX.HsJqEmNTszGecsKqFB37i84nBXxqf4ETgrKmKmBvMGHC@FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE", - "gateway": "FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE" - }, - { - "id": "shipyard-telegram-29", - "description": "Nym Telegram Service Provider", - "address": "BiCSyovpFMuSnTvF2TdiuZwrytXDrd9AH47ZMcCxscVC.G9YpdicA9BBNoVHDgjWjgt17wv5WYKWcbE3vPJJVpSJD@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", - "gateway":"GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" - }, - { - "id": "shipyard-telegram-30", - "description": "Nym Telegram Service Provider", - "address": "AQRRAs9oc8QWXAFBs44YhCKUny7AyLsfLy91pwmGgxuf.CWUKoKA1afSKyw5BnFJJg19UDgnaVATupsFhQpyTEBHJ@EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w", - "gateway": "EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w" - }, - { - "id": "shipyard-telegram-31", - "description": "Nym Telegram Service Provider", - "address": "6YqjAZK3Pr1ngiBLcDkotboB5WiN6k6NPpbXvShH4pR5.9Ss6VW3Xbyi8LuxduNNwnXEv9njHCQ2PLSP1UK6tsoa5@42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD", - "gateway": "42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD" - }, - { - "id": "shipyard-telegram-32", - "description": "Nym Telegram Service Provider", - "address": "EmYWLeybmj86Vzr62vxuZ3T15jwMNHggzK7sQwid96yp.GyaF9WprSr56cxUdGf5TpcUvAjb2VbAr8CVBrmBUYAaw@GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC", - "gateway": "GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC" - }, - { - "id": "shipyard-telegram-33", - "description": "Nym Telegram Service Provider", - "address": "4PDb96cck5btTj6G7rsomqwHJsp4qu8uPvFCbwHfjFUx.C5dKbaoakH7egsZvAueRbwLFbmxnQaVMeSr6QTMpuBAA@58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY", - "gateway": "58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY" - }, - { - "id": "shipyard-telegram-34", - "description": "Nym Telegram Service Provider", - "address": "BeZbeMf9vcpUf368qDd85dtLwXLj4Ee5bsHMB2fUD8uX.HELVbppkwU1jmzUAUrCEbHeJfVciSeo8VGAkbJSpwxsb@ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY", - "gateway":"ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY" - }, - { - "id": "shipyard-telegram-35", - "description": "Nym Telegram Service Provider", - "address": "Bp4JRFyf7GB9L9J95AqMPnz9zbGmPnViA5fDXKeNraLJ.D6CTdcjJVxDmH2UQvzXuPWg9Se9xXYe76uDMypXvhzd7@6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N", - "gateway": "6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N" - }, - { - "id": "shipyard-telegram-36", - "description": "Nym Telegram Service Provider", - "address": "91h7io6BGhVjbtC7dbbRcScyTJcTfnMsTQZ6aWMVsrWR.Epb4hANXCp8cGEY3wSgawux991ti9Z5Y1FHTMzAKFa6E@DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe", - "gateway": "DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe" - }, - { - "id": "shipyard-telegram-37", - "description": "Nym Telegram Service Provider", - "address": "Cy2wuwKpWZ3iWzKU3ZWL1qqcVfJ5Cq85dU7UHVWwv2gc.9AhC9b2zVcLnXLGriMdxjpsWJpq6iAdCavDi63udbL89@678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf", - "gateway": "678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf" - }, - { - "id": "shipyard-telegram-38", - "description": "Nym Telegram Service Provider", - "address": "GgUeUWW1NRSuquZYeZf3WkppE92EQUHJrFjNZtYU1jow.CSEjwrRi4f4uyw7N6L2LPKw2tB8spcMbFu99wHZzFZSj@77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm", - "gateway": "77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm" - }, - { - "id": "shipyard-telegram-39", - "description": "Nym Telegram Service Provider", - "address": "kz4zWwSkYiQxqxXFPNcGUByTPQWXascD9RfYsmSxY7n.ajp3SjbBVBjrU9nXpSQXAXzbb6EHJJyhbY6cc1ajayx@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYf", - "gateway": "HyS2UZtZX3kQXdazbdE99DhCjBXjbG61LC9QsmXwbxrU" - } - ] - }, - { - "id": "blockstream", - "description": "Blockstream Green", - "items": [ - { - "id": "nym-blockstream", - "description": "Nym Blockstream Green Service Provider", - "address": "GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", - "gateway": "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW" - } - ] - } -]`); -export const Loaded = () => ( - - - -); - -export const ServiceAlreadySelected = () => ( - - console.log('New service provider selected: ', serviceProvider)} - /> - -); diff --git a/nym-connect/desktop/src/components/ServiceProviderSelector.tsx b/nym-connect/desktop/src/components/ServiceProviderSelector.tsx deleted file mode 100644 index 741465dac4..0000000000 --- a/nym-connect/desktop/src/components/ServiceProviderSelector.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import React, { useEffect, useMemo } from 'react'; -import { Box, CircularProgress, MenuItem, Stack, TextField, Tooltip, Typography } from '@mui/material'; -import { Service, ServiceProvider, Services } from '../types/directory'; -import { useTauriEvents } from '../utils'; - -type ServiceWithRandomSp = { - id: string; - description: string; - sp: ServiceProvider; -}; - -const defaultServiceValue = { id: '', description: '', items: [] }; - -export const ServiceProviderSelector: FCWithChildren<{ - onChange?: (serviceProvider?: ServiceProvider) => void; - services?: Services; - currentSp?: ServiceProvider; -}> = ({ services, currentSp, onChange }) => { - const [service, setService] = React.useState(defaultServiceValue); - const [serviceProvider, setServiceProvider] = React.useState(currentSp); - const [resetTrigger, setResetTrigger] = React.useState(new Date().toISOString()); - - const handleSelectSp = (newServiceProvider?: ServiceProvider) => { - if (newServiceProvider && newServiceProvider !== currentSp) { - setServiceProvider(newServiceProvider); - onChange?.(newServiceProvider); - } - }; - - // when the user clears local storage, reset the selector - useTauriEvents('help://clear-storage', () => { - setService(defaultServiceValue); - setServiceProvider(undefined); - onChange?.(undefined); - setResetTrigger(new Date().toISOString()); - }); - - useEffect(() => { - if (!serviceProvider && currentSp) { - setServiceProvider(currentSp); - } - }, [currentSp]); - - useEffect(() => { - if (services && serviceProvider) { - // retrieve the service corresponding to this service provider - - const match = services.find((s) => - s.items.some( - ({ id, address, gateway }) => - id === serviceProvider.id && address === serviceProvider.address && gateway === serviceProvider.gateway, - ), - ); - - if (match) { - setService(match); - } - } - }, [serviceProvider, services]); - - if (!services) { - return ( - - theme.palette.common.white}> - - Loading services... - - - ); - } - - const servicesWithRandomSp: ServiceWithRandomSp[] = useMemo( - () => - services.map(({ id, items, description }) => ({ - id, - description, - sp: items[Math.floor(Math.random() * items.length)], - })), - [services, resetTrigger], - ); - - if (!service) return null; - - return ( - - - {servicesWithRandomSp.map(({ id, description, sp }) => ( - handleSelectSp(sp)}> - - - {sp.id} - - - {sp.description} - - - Gateway {sp.gateway.slice(0, 10)}... - - - Provider {sp.address.slice(0, 10)}... - - - } - arrow - placement="top" - > - {description} - - - ))} - - - ); -}; diff --git a/nym-connect/desktop/src/components/ServiceSelector.stories.tsx b/nym-connect/desktop/src/components/ServiceSelector.stories.tsx deleted file mode 100644 index 56be7c19ee..0000000000 --- a/nym-connect/desktop/src/components/ServiceSelector.stories.tsx +++ /dev/null @@ -1,342 +0,0 @@ -import * as React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Box } from '@mui/material'; -import { ServiceSelector } from './ServiceSelector'; -import { Services } from '../types/directory'; - -export default { - title: 'Components/Service Selector', - component: ServiceSelector, -} as ComponentMeta; - -const width = 240; - -export const Loading = () => ( - - - -); - -const services: Services = JSON.parse(`[ - { - "id": "keybase", - "description": "Keybase", - "items": [ - { - "id": "nym-keybase", - "description": "Nym Keybase Service Provider", - "address": "Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf", - "gateway": "Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf" - }, - { - "id": "shipyard-keybase-1", - "description": "Nym Keybase Service Provider", - "address": "D55ksecHzY6vAeqk8MCTzCfj2pqwJeKCKZCUUGnwGnn3.FS42vXS5a6GNTb1qk3aVk5mjSiJCAuawbBVyQZZVfhvt@DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn", - "gateway": "DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn" - }, - { - "id": "shipyard-keybase-2", - "description": "Nym Keybase Service Provider", - "address": "DFdDtW7LNBATxQ4ef3jNbqs3cRE8b9wDZTCctHCQRULa.4AbKiTNVUwYFWHhy98o5pT9dELiUrkXoJQ9wHqPgf6GV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN", - "gateway": "GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN" - }, - { - "id": "shipyard-keybase-3", - "description": "Nym Keybase Service Provider", - "address": "6Y1HE1jJ92P9yoHer11TR4A2NdZePrLGaBNFf65MnYGe.FwXoh217odQDWNmViqzNX28fauYrjB3PYLrVvpqnQrX4@5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz", - "gateway": "5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz" - }, - { - "id": "shipyard-keybase-4", - "description": "Nym Keybase Service Provider", - "address": "3zzhLtWvaJgn755MkRckG5aRnoTZich8ASn395iSsTgj.J1R5VuxXbh2eNHiaRbrwbKGXrrEQcHKLdzf8eg9HTB6q@3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj", - "gateway": "3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj" - }, - { - "id": "shipyard-keybase-5", - "description": "Nym Keybase Service Provider", - "address": "CHuXdZJYQ8xH7ekgN9gAuVtQ7ZikjjHEZY5BSN7yc5mN.29dFvqicKQQQvoX1vup44mspmc249RH5xgLibWMwTYGT@CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9", - "gateway": "CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9" - } - ] - }, - { - "id": "electrum", - "description": "Electrum Wallet", - "items": [ - { - "id": "nym-electrum", - "description": "Nym Electrum Service Provider", - "address": "DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh", - "gateway": "2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh" - }, - { - "id": "shipyard-electrum-1", - "description": "Nym Electrum Service Provider", - "address": "8Tb73cFQpXCLpgxEA2VSDru2hHrcZ3KQcyMsGbxcTjBp.4x5tu66k8YkHk4tYac1qwEFbNq5WsKiX5kR51q5KKH88@4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd", - "gateway": "4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd" - }, - { - "id": "shipyard-electrum-2", - "description": "Nym Electrum Service Provider", - "address": "GR6z31MwCsvxHrnvvVN1Cpasd8aQ1giwQqPTZM9dN7VH.5rEiqakSPDrBtKmvpU8Shnhz6gRM85JLoB7AX4h7PJYr@5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD", - "gateway": "5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD" - } - ] - }, - { - "id": "telegram", - "description": "Telegram", - "items": [ - { - "id": "shipyard-telegram-2", - "description": "Nym Telegram Service Provider", - "address": "C4w6ewbQtoaZEeoaaNw1xVASChqo4WVjNfuYEUFjZxpc.8F1D7rQXf2jGoj1Ken7PiGDM8HS2Ug79wSoc9nZ1iqh1@62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve", - "gateway": "62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve" - }, - { - "id": "shipyard-telegram-3", - "description": "Nym Telegram Service Provider", - "address": "DStL3BEUZuQZfbij1KAY3BvJh8rC5jpr9mc6AQ6aTLUu.Ax9foYaKfFgX6g8y393GoNpKkKrnDGFGRZwxDv9R7X6M@FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE", - "gateway": "FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE" - }, - { - "id": "shipyard-telegram-4", - "description": "Nym Telegram Service Provider", - "address": "8gRdGTzsDxYzpasRQhsRg59MCgNNhnfag2oFfwwZPXnB.DtDrGz7ScVm4o7sN4K3CYUJveYgz7fcXELBVLNDfMS9Y@3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh", - "gateway": "3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh" - }, - { - "id": "shipyard-telegram-5", - "description": "Nym Telegram Service Provider", - "address": "AR3oEM6Uvmfs6fyddwSehoBUKCFxz7MdFi4z7aahuHuY.3ZKapg9A3Py1PXhyLbCJr8ZbJsEV6NZdN1WJaGGut5tj@EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp", - "gateway": "EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp" - }, - { - "id": "shipyard-telegram-6", - "description": "Nym Telegram Service Provider", - "address": "7n1BYhsXSwcr8Qim8AqZTAodqFia4QG6T7CRc1ihQHpv.7o4trpGqu2LHMUiXc3dddgfGET1CFFcAK9gKYoHoSn5e@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr", - "gateway": "BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr" - }, - { - "id": "shipyard-telegram-7", - "description": "Nym Telegram Service Provider", - "address": "Gv4TWhUKrvJfqh1jBRPGEQrikNZvZse2kS3ZgN9Z2nAZ.7KGPaaqUEum2C59jLvw7f8Ug8a48YuZdjjZu3t4JES4U@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", - "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" - }, - { - "id": "shipyard-telegram-8", - "description": "Nym Telegram Service Provider", - "address": "8Mqgp12cpF6FSXMeqzxgFgQXvTSapyNqGAi5wy7ub4ge.7z7PDsiJGiGxGz4p77v5L5fZhXBJ5qNZ8CgJwYNr6H6J", - "gateway": "3zd3wrCK8Dz5TXrcvk5dG5s9EEdf4Ck1v9VgBPMMFVkR" - }, - { - "id": "shipyard-telegram-9", - "description": "Nym Telegram Service Provider", - "address": "F3N5eiPDZcGFC985Go4Mpv8p9uxFD1L3jRUdrLCbrZLm.EyTxWwwTwYpPrJBmc97GLd1LpUAphjptS5y1ed182bGk@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", - "gateway": "GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" - }, - { - "id": "shipyard-telegram-10", - "description": "Nym Telegram Service Provider", - "address": "G7y7e1nVBr8fmQSzdeAxXnCmmmJb5k8N3E8LBV31KE5g.GRRUCj6t6cCUUjakmTWzidMLiYA7EdCedKnup8osaBC6@AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc", - "gateway": "AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc" - }, - { - "id": "shipyard-telegram-11", - "description": "Nym Telegram Service Provider", - "address": "2kq9Z7RyDZtb8kxXjyP3ZT8VMWHg6JXFDChGuuNBk7Hw.F5XYbBaGSoF8qAo8faPcaNRPHEq3Y25BDcwESeabUS9S@HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM", - "gateway": "HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM" - }, - { - "id": "shipyard-telegram-12", - "description": "Nym Telegram Service Provider", - "address": "GegdtpNzYj4QCgpih9Kxv7ZVZxmVdxYHsDkiPsbT71XG.E8xtE8mrapjzFtyuziZSrsScAKhwZMH5wNpKWtKfzJ5Y@9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J", - "gateway": "9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J" - }, - { - "id": "shipyard-telegram-13", - "description": "Nym Telegram Service Provider", - "address": "4SsrDQeEtG3mpeD9nN5CDdGaCsxFvNeYMhoviDzNNB9f.GyqG6iK5rBvhe3HXLR11m6ULpf13ATgYvkkidLmteDLs@5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS", - "gateway": "5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS" - }, - { - "id": "shipyard-telegram-14", - "description": "Nym Telegram Service Provider", - "address": "9JoHRu2RrSD1fjbj9NSTASgjv9Szep7Nhd9L2PywxbBi.AZhAUDNX6iH8BqXyR5c7TJuzpwMEvDXrabNLGuRukvVf@9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS", - "gateway": "9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS" - }, - { - "id": "shipyard-telegram-15", - "description": "Nym Telegram Service Provider", - "address": "3K174ijjXqCkhMDT9xLcqjS4MXk2QsqZt4PdgNcuUrnn.BNnHnQmWoj6Uo6kkS1QkPqsdHaXrcwyR9F6MnnzDkZJL@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", - "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" - }, - { - "id": "shipyard-telegram-16", - "description": "Nym Telegram Service Provider", - "address": "BqX5Q3MEcbTnM39hUswQchLW68SrqbhL8K5ucrLmtP39.AWrVsFoVC9s6KjdpcasATmZPA3GtMsUxcfHpAkuNdtFG@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS", - "gateway": "Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS" - }, - { - "id": "shipyard-telegram-17", - "description": "Nym Telegram Service Provider", - "address": "2tQxccgcqdkuUvLqgiEkEN4rNRZ5QknygnKAFcS4gfoe.EVrY5q5sqDqBUbS3wHsRRZhk2MAw1S17hNoH1Bicyv7n@DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom", - "gateway": "DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom" - }, - { - "id": "shipyard-telegram-18", - "description": "Nym Telegram Service Provider", - "address": "8YG1rcEauJA814Nd7hSxjNe2UrRwrGsrXTm1Cmd3gRrU.FxYaYqpNN8PciNsySs3zYPrTB1J8AYUu9DBsM2vVDDfF@7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog", - "gateway": "7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog" - }, - { - "id": "shipyard-telegram-19", - "description": "Nym Telegram Service Provider", - "address": "HPiXADVFLwLQPNpPtyYefzvYntC6tp9UJ5fJZGfkqvDt.2EUUxmeT3AiaUzAcE5SyXRAk8a2JXBkRz4B8McSdkrST@9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD", - "gateway": "9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD" - }, - { - "id": "shipyard-telegram-20", - "description": "Nym Telegram Service Provider", - "address": "2QLnEEnTmf2NRWtcQPWBeRcg7Hej5WSPWRWwtTpEEZWF.BheS78ozc8ngvhsXNNnshdJzpoYsmEvhfn3WKUYF5dRU@C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF", - "gateway": "C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF" - }, - { - "id": "shipyard-telegram-21", - "description": "Nym Telegram Service Provider", - "address": "FuBbnwiANfaXZnn683jBapK5XVm5ttgZSykU3vqPSHoD.94MFGv1VcBLTkRwzBDQUkWjvqtZYVBrJg2Q8JGbizcib@CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK", - "gateway": "CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK" - }, - { - "id": "shipyard-telegram-22", - "description": "Nym Telegram Service Provider", - "address": "9EbQx5jQznSVbftFom7sqUSHAACrsfvMhrzhaFt4A3SZ.D1FQCirL4YKwfcmtMGvB5Rugt5sAzGEhdSjJ3bHVQRZ@7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4", - "gateway": "7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4" - }, - { - "id": "shipyard-telegram-24", - "description": "Nym Telegram Service Provider", - "address": "6Umawwvf551VyB3Ko46NgKLqJdTFJeToCM67mrTmM3G.3A4sesBac4KGuMTFjvYBwLpksMJvbMbteGJQgmm4PV4Y@AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR", - "gateway": "AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR" - }, - { - "id": "shipyard-telegram-25", - "description": "Nym Telegram Service Provider", - "address": "CDtxTeoyqq83JpV9G8cR5HRHRdMMaVspQsCwH3Qnajt3.F5EHK9HFcdGrE2hqA7bK9AUmkbihujYDhtNNqHKxW765@BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH", - "gateway": "BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH" - }, - { - "id": "shipyard-telegram-26", - "description": "Nym Telegram Service Provider", - "address": "HukZkLG2DoarQEqaoDLuqW1GFf2NSHDUMGBZiyJGRYJD.9GyU8wPsyzcvRjcyk8hiNpTJbXCmq5F3VoVhFBZYuHR3@GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN", - "gateway": "GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN" - }, - { - "id": "shipyard-telegram-27", - "description": "Nym Telegram Service Provider", - "address": "773y8iMVJiRk4dRbjQzkJVbrei4TwkePNE5WTEttt77d.3Mw47C9XZj3oAzk1iSqC5Y36tbBsjtaTtdgaHM3Zsdma@7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv", - "gateway": "7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv" - }, - { - "id": "shipyard-telegram-28", - "description": "Nym Telegram Service Provider", - "address": "6jQJEorCu7YiP9HdDaMeHxcNhxeNmZ1kpd836GnqLZX.HsJqEmNTszGecsKqFB37i84nBXxqf4ETgrKmKmBvMGHC@FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE", - "gateway": "FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE" - }, - { - "id": "shipyard-telegram-29", - "description": "Nym Telegram Service Provider", - "address": "BiCSyovpFMuSnTvF2TdiuZwrytXDrd9AH47ZMcCxscVC.G9YpdicA9BBNoVHDgjWjgt17wv5WYKWcbE3vPJJVpSJD@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", - "gateway":"GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" - }, - { - "id": "shipyard-telegram-30", - "description": "Nym Telegram Service Provider", - "address": "AQRRAs9oc8QWXAFBs44YhCKUny7AyLsfLy91pwmGgxuf.CWUKoKA1afSKyw5BnFJJg19UDgnaVATupsFhQpyTEBHJ@EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w", - "gateway": "EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w" - }, - { - "id": "shipyard-telegram-31", - "description": "Nym Telegram Service Provider", - "address": "6YqjAZK3Pr1ngiBLcDkotboB5WiN6k6NPpbXvShH4pR5.9Ss6VW3Xbyi8LuxduNNwnXEv9njHCQ2PLSP1UK6tsoa5@42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD", - "gateway": "42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD" - }, - { - "id": "shipyard-telegram-32", - "description": "Nym Telegram Service Provider", - "address": "EmYWLeybmj86Vzr62vxuZ3T15jwMNHggzK7sQwid96yp.GyaF9WprSr56cxUdGf5TpcUvAjb2VbAr8CVBrmBUYAaw@GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC", - "gateway": "GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC" - }, - { - "id": "shipyard-telegram-33", - "description": "Nym Telegram Service Provider", - "address": "4PDb96cck5btTj6G7rsomqwHJsp4qu8uPvFCbwHfjFUx.C5dKbaoakH7egsZvAueRbwLFbmxnQaVMeSr6QTMpuBAA@58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY", - "gateway": "58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY" - }, - { - "id": "shipyard-telegram-34", - "description": "Nym Telegram Service Provider", - "address": "BeZbeMf9vcpUf368qDd85dtLwXLj4Ee5bsHMB2fUD8uX.HELVbppkwU1jmzUAUrCEbHeJfVciSeo8VGAkbJSpwxsb@ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY", - "gateway":"ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY" - }, - { - "id": "shipyard-telegram-35", - "description": "Nym Telegram Service Provider", - "address": "Bp4JRFyf7GB9L9J95AqMPnz9zbGmPnViA5fDXKeNraLJ.D6CTdcjJVxDmH2UQvzXuPWg9Se9xXYe76uDMypXvhzd7@6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N", - "gateway": "6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N" - }, - { - "id": "shipyard-telegram-36", - "description": "Nym Telegram Service Provider", - "address": "91h7io6BGhVjbtC7dbbRcScyTJcTfnMsTQZ6aWMVsrWR.Epb4hANXCp8cGEY3wSgawux991ti9Z5Y1FHTMzAKFa6E@DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe", - "gateway": "DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe" - }, - { - "id": "shipyard-telegram-37", - "description": "Nym Telegram Service Provider", - "address": "Cy2wuwKpWZ3iWzKU3ZWL1qqcVfJ5Cq85dU7UHVWwv2gc.9AhC9b2zVcLnXLGriMdxjpsWJpq6iAdCavDi63udbL89@678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf", - "gateway": "678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf" - }, - { - "id": "shipyard-telegram-38", - "description": "Nym Telegram Service Provider", - "address": "GgUeUWW1NRSuquZYeZf3WkppE92EQUHJrFjNZtYU1jow.CSEjwrRi4f4uyw7N6L2LPKw2tB8spcMbFu99wHZzFZSj@77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm", - "gateway": "77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm" - }, - { - "id": "shipyard-telegram-39", - "description": "Nym Telegram Service Provider", - "address": "kz4zWwSkYiQxqxXFPNcGUByTPQWXascD9RfYsmSxY7n.ajp3SjbBVBjrU9nXpSQXAXzbb6EHJJyhbY6cc1ajayx@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYf", - "gateway": "HyS2UZtZX3kQXdazbdE99DhCjBXjbG61LC9QsmXwbxrU" - } - ] - }, - { - "id": "blockstream", - "description": "Blockstream Green", - "items": [ - { - "id": "nym-blockstream", - "description": "Nym Blockstream Green Service Provider", - "address": "GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", - "gateway": "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW" - } - ] - } -]`); -export const Loaded = () => ( - - - -); - -export const ServiceAlreadySelected = () => ( - - console.log('New service provider selected: ', serviceProvider)} - /> - -); diff --git a/nym-connect/desktop/src/components/ServiceSelector.tsx b/nym-connect/desktop/src/components/ServiceSelector.tsx deleted file mode 100644 index 5eb8361d3c..0000000000 --- a/nym-connect/desktop/src/components/ServiceSelector.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import React, { useEffect } from 'react'; -import { - Box, - CircularProgress, - Divider, - FormControl, - InputLabel, - MenuItem, - Select, - Stack, - Typography, -} from '@mui/material'; -import { Service, ServiceProvider, Services } from '../types/directory'; -import { useTauriEvents } from '../utils'; -import { ServiceProviderPopup } from './ServiceProviderPopup'; - -export const ServiceSelector: FCWithChildren<{ - onChange?: (serviceProvider?: ServiceProvider) => void; - services?: Services; - currentSp?: ServiceProvider; -}> = ({ services, currentSp, onChange }) => { - const [service, setService] = React.useState(); - const [serviceProvider, setServiceProvider] = React.useState(currentSp); - const [isPopupVisible, setPopupVisible] = React.useState(false); - - const getService = () => { - if (!services || !currentSp) { - return undefined; - } - return services.find((s) => - s.items.some( - ({ id, address, gateway }) => - id === currentSp.id && address === currentSp.address && gateway === currentSp.gateway, - ), - ); - }; - - useEffect(() => { - if (!service && currentSp) { - setServiceProvider(currentSp); - setService(getService()); - } - }, [currentSp, services]); - - /** - * Gets a random service provider from the currently selected service. - * - * If there is no service selected, or it does not have items, `undefined` is returned. - */ - const getRandomServiceProviderForService = (serviceToUse?: Service): ServiceProvider | undefined => { - if (!serviceToUse?.items.length) { - return undefined; - } - return serviceToUse.items[Math.floor(Math.random() * serviceToUse.items.length)]; - }; - - const handleServiceSelected = React.useCallback( - (newService?: Service) => { - console.log(newService?.id, service?.id); - // if the user has chosen a new service, then pick a random service provider - if (newService?.id !== service?.id) { - const newServiceProvider = getRandomServiceProviderForService(newService); - setServiceProvider(newServiceProvider); - onChange?.(newServiceProvider); - setService(newService); - } - }, - [service], - ); - - // clears the display and fire on change (to trigger upstream storage clearance) - const clearServiceProviderAndFireOnChange = () => { - setService(undefined); - setServiceProvider(undefined); - onChange?.(undefined); - }; - - // when the user clears local storage, reset the selector - useTauriEvents('help://clear-storage', () => { - clearServiceProviderAndFireOnChange(); - }); - - const handleAdvancedSpChange = (newServiceProvider?: ServiceProvider, newService?: Service) => { - setPopupVisible(false); - setService(newService); - setServiceProvider(newServiceProvider); - onChange?.(newServiceProvider); - }; - - const handleNewService = (newServiceId?: string) => { - const newService = (services || []).find((s) => s.id === newServiceId); - setService(newService); - }; - - if (!services) { - return ( - - theme.palette.common.white}> - - Loading services... - - - ); - } - - return ( - - - - Select a service - - - - setPopupVisible(false)} - onServiceProviderChanged={handleAdvancedSpChange} - /> - - ); -}; diff --git a/nym-connect/desktop/src/components/TooltipInfo.tsx b/nym-connect/desktop/src/components/TooltipInfo.tsx index 2d76c6859e..7a78242c08 100644 --- a/nym-connect/desktop/src/components/TooltipInfo.tsx +++ b/nym-connect/desktop/src/components/TooltipInfo.tsx @@ -1,15 +1,21 @@ import React from 'react'; import { Divider, Stack, Typography } from '@mui/material'; -import { ServiceProvider } from 'src/types/directory'; +import { ServiceProvider, Gateway } from 'src/types/directory'; -export const ServiceProviderInfo = ({ serviceProvider }: { serviceProvider: ServiceProvider }) => ( +export const ServiceProviderInfo = ({ + serviceProvider, + gateway, +}: { + serviceProvider: ServiceProvider; + gateway: Gateway; +}) => ( Connection info - Gateway {serviceProvider.gateway} + Gateway {gateway.identity} diff --git a/nym-connect/desktop/src/context/main.tsx b/nym-connect/desktop/src/context/main.tsx index f51e73389d..46d3312fac 100644 --- a/nym-connect/desktop/src/context/main.tsx +++ b/nym-connect/desktop/src/context/main.tsx @@ -9,7 +9,7 @@ import { UserDefinedGateway, UserDefinedSPAddress } from 'src/types/service-prov import { getItemFromStorage, setItemInStorage } from 'src/utils'; import { ConnectionStatusKind, GatewayPerformance, PrivacyLevel, UserData } from '../types'; import { ConnectionStatsItem } from '../components/ConnectionStats'; -import { ServiceProvider } from '../types/directory'; +import { ServiceProvider, Gateway } from '../types/directory'; import initSentry from '../sentry'; const FORAGE_GATEWAY_KEY = 'nym-connect-user-gateway'; @@ -27,17 +27,20 @@ export type TClientContext = { error?: Error; gatewayPerformance: GatewayPerformance; selectedProvider?: ServiceProvider; + selectedGateway?: Gateway; showInfoModal: boolean; userDefinedGateway?: UserDefinedGateway; userDefinedSPAddress: UserDefinedSPAddress; serviceProviders?: ServiceProvider[]; + gateways?: Gateway[]; setMode: (mode: ModeType) => void; clearError: () => void; setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void; setConnectionStats: (connectionStats: ConnectionStatsItem[] | undefined) => void; setConnectedSince: (connectedSince: DateTime | undefined) => void; setShowInfoModal: (show: boolean) => void; - setSerivceProvider: () => void; + setServiceProvider: () => void; + setGateway: () => void; startConnecting: () => Promise; startDisconnecting: () => Promise; setUserDefinedGateway: React.Dispatch>; @@ -46,6 +49,10 @@ export type TClientContext = { setPrivacyLevel: (value: PrivacyLevel) => Promise; }; +function getRandomFromList(items: T[]): T { + return items[Math.floor(Math.random() * items.length)]; +} + export const ClientContext = createContext({} as TClientContext); export const ClientContextProvider: FCWithChildren = ({ children }) => { @@ -54,7 +61,9 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { const [connectionStats, setConnectionStats] = useState(); const [connectedSince, setConnectedSince] = useState(); const [selectedProvider, setSelectedProvider] = React.useState(); + const [selectedGateway, setSelectedGateway] = React.useState(); const [serviceProviders, setServiceProviders] = React.useState(); + const [gateways, setGateways] = React.useState(); const [error, setError] = useState(); const [appVersion, setAppVersion] = useState(); const [gatewayPerformance, setGatewayPerformance] = useState('Good'); @@ -103,13 +112,15 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { }, [userDefinedSPAddress]); const initialiseApp = async () => { - const services = await invoke('get_services'); + const fetchedServices = await invoke('get_services'); + const fetchedGateways = await invoke('get_gateways'); const AppVersion = await getAppVersion(); const storedUserDefinedGateway = await getItemFromStorage({ key: FORAGE_GATEWAY_KEY }); const storedUserDefinedSP = await getItemFromStorage({ key: FORAGE_SP_KEY }); setAppVersion(AppVersion); - setServiceProviders(services as ServiceProvider[]); + setServiceProviders(fetchedServices); + setGateways(fetchedGateways); if (storedUserDefinedGateway) { setUserDefinedGateway(storedUserDefinedGateway); @@ -162,39 +173,42 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { const shouldUseUserGateway = !!userDefinedGateway.gateway && userDefinedGateway.isActive; const shouldUseUserSP = !!userDefinedSPAddress.address && userDefinedSPAddress.isActive; - const setServiceProvider = async (newServiceProvider: ServiceProvider) => { - await invoke('set_gateway', { - gateway: shouldUseUserGateway ? userDefinedGateway.gateway : newServiceProvider.gateway, - }); - await invoke('set_service_provider', { - serviceProvider: shouldUseUserSP ? userDefinedSPAddress.address : newServiceProvider.address, - }); - }; - - const getRandomSPFromList = (services: ServiceProvider[]) => { - const randomSelection = services[Math.floor(Math.random() * services.length)]; - return randomSelection; - }; - const buildServiceProvider = async (serviceProvider: ServiceProvider) => { const sp = { ...serviceProvider }; - - if (shouldUseUserGateway) sp.gateway = userDefinedGateway.gateway as string; if (shouldUseUserSP) sp.address = userDefinedSPAddress.address as string; - return sp; }; - const setSerivceProvider = async () => { + const buildGateway = async (gateway: Gateway) => { + const gw = { ...gateway }; + if (shouldUseUserGateway) gw.identity = userDefinedGateway.gateway as string; + return gw; + }; + + const setServiceProvider = async () => { if (serviceProviders) { - const randomServiceProvider = getRandomSPFromList(serviceProviders); + const randomServiceProvider = getRandomFromList(serviceProviders); const withUserDefinitions = await buildServiceProvider(randomServiceProvider); - await setServiceProvider(withUserDefinitions); + await invoke('set_service_provider', { + serviceProvider: shouldUseUserSP ? userDefinedSPAddress.address : withUserDefinitions.address, + }); setSelectedProvider(withUserDefinitions); } return undefined; }; + const setGateway = async () => { + if (gateways) { + const randomGateway = getRandomFromList(gateways); + const withUserDefinitions = await buildGateway(randomGateway); + await invoke('set_gateway', { + gateway: shouldUseUserGateway ? userDefinedGateway.gateway : withUserDefinitions.identity, + }); + setSelectedGateway(withUserDefinitions); + } + return undefined; + }; + const clearError = () => setError(undefined); const setMonitoring = async (value: boolean) => { @@ -222,11 +236,13 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { showInfoModal, setConnectionStats, selectedProvider, + selectedGateway, serviceProviders, connectedSince, userData, setConnectedSince, - setSerivceProvider, + setServiceProvider, + setGateway, startConnecting, startDisconnecting, gatewayPerformance, @@ -250,6 +266,7 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { connectedSince, gatewayPerformance, selectedProvider, + selectedGateway, userDefinedGateway, userDefinedSPAddress, userData, diff --git a/nym-connect/desktop/src/context/mocks/main.tsx b/nym-connect/desktop/src/context/mocks/main.tsx index 8fdd8518c9..46a5f50298 100644 --- a/nym-connect/desktop/src/context/mocks/main.tsx +++ b/nym-connect/desktop/src/context/mocks/main.tsx @@ -6,7 +6,7 @@ const mockValues: TClientContext = { appVersion: 'v1.x.x', mode: 'dark', connectionStatus: ConnectionStatusKind.disconnected, - selectedProvider: { id: '1', description: 'Keybase service provider', gateway: 'abc123', address: '123abc' }, + selectedProvider: { id: '1', description: 'Keybase service provider', address: '123abc' }, gatewayPerformance: 'Good', showInfoModal: false, userDefinedGateway: { isActive: false, gateway: '' }, @@ -20,7 +20,8 @@ const mockValues: TClientContext = { setConnectionStatus: () => {}, startConnecting: async () => {}, startDisconnecting: async () => {}, - setSerivceProvider: () => {}, + setServiceProvider: () => {}, + setGateway: () => {}, setUserDefinedGateway: () => {}, setUserDefinedSPAddress: () => {}, setMonitoring: async () => {}, diff --git a/nym-connect/desktop/src/pages/connection/Connected.tsx b/nym-connect/desktop/src/pages/connection/Connected.tsx index 5e06b8828e..1408b8644f 100644 --- a/nym-connect/desktop/src/pages/connection/Connected.tsx +++ b/nym-connect/desktop/src/pages/connection/Connected.tsx @@ -7,7 +7,7 @@ import { ConnectionStatus } from 'src/components/ConnectionStatus'; import { ConnectionStatusKind, GatewayPerformance } from 'src/types'; import { ConnectionStatsItem } from 'src/components/ConnectionStats'; import { IpAddressAndPort } from 'src/components/IpAddressAndPort'; -import { ServiceProvider } from 'src/types/directory'; +import { ServiceProvider, Gateway } from 'src/types/directory'; import { ExperimentalWarning } from 'src/components/ExperimentalWarning'; import { ConnectionLayout } from 'src/layouts/ConnectionLayout'; import { PowerButton } from 'src/components/PowerButton/PowerButton'; @@ -26,6 +26,7 @@ export const Connected: FCWithChildren<{ busy?: boolean; isError?: boolean; serviceProvider?: ServiceProvider; + gateway?: Gateway; clearError: () => void; onConnectClick: (status: ConnectionStatusKind) => void; closeInfoModal: () => void; @@ -40,6 +41,7 @@ export const Connected: FCWithChildren<{ busy, isError, serviceProvider, + gateway, clearError, onConnectClick, closeInfoModal, @@ -54,6 +56,7 @@ export const Connected: FCWithChildren<{ status={ConnectionStatusKind.connected} gatewayPerformance={gatewayPerformance} serviceProvider={serviceProvider} + gateway={gateway} /> diff --git a/nym-connect/desktop/src/pages/connection/index.tsx b/nym-connect/desktop/src/pages/connection/index.tsx index bbdf0a6125..2f7ebc5899 100644 --- a/nym-connect/desktop/src/pages/connection/index.tsx +++ b/nym-connect/desktop/src/pages/connection/index.tsx @@ -30,7 +30,8 @@ export const ConnectionPage = () => { switch (currentStatus) { case 'disconnected': Sentry.captureMessage('start connect', 'info'); - await context.setSerivceProvider(); + await context.setServiceProvider(); + await context.setGateway(); await context.startConnecting(); context.setConnectedSince(DateTime.now()); context.setShowInfoModal(true); @@ -61,6 +62,7 @@ export const ConnectionPage = () => { gatewayPerformance={context.gatewayPerformance} connectedSince={context.connectedSince} serviceProvider={context.selectedProvider} + gateway={context.selectedGateway} closeInfoModal={closeInfoModal} stats={[ { diff --git a/nym-connect/desktop/src/stories/AppFlow.stories.tsx b/nym-connect/desktop/src/stories/AppFlow.stories.tsx index c00cb2aa9e..c88f32bae2 100644 --- a/nym-connect/desktop/src/stories/AppFlow.stories.tsx +++ b/nym-connect/desktop/src/stories/AppFlow.stories.tsx @@ -29,7 +29,6 @@ export const Mock: ComponentStory = () => { id: 'nym-keybase', description: 'Nym Keybase Service Provider', address: '1234.5678', - gateway: 'abcedf', }, ], }, diff --git a/nym-connect/desktop/src/stories/ConnectedLayout.stories.tsx b/nym-connect/desktop/src/stories/ConnectedLayout.stories.tsx index 426252dc63..b0e72587c2 100644 --- a/nym-connect/desktop/src/stories/ConnectedLayout.stories.tsx +++ b/nym-connect/desktop/src/stories/ConnectedLayout.stories.tsx @@ -22,7 +22,7 @@ export const Default: ComponentStory = () => ( status={ConnectionStatusKind.connected} connectedSince={DateTime.now()} ipAddress="127.0.0.1" - serviceProvider={{ id: 'service 1', description: 'good services', address: 'abc123', gateway: '8910xyz' }} + serviceProvider={{ id: 'service 1', description: 'good services', address: 'abc123' }} port={1080} stats={[ { diff --git a/nym-connect/desktop/src/stories/DefaultLayout.stories.tsx b/nym-connect/desktop/src/stories/DefaultLayout.stories.tsx index 4d1b869a10..00a2c5b684 100644 --- a/nym-connect/desktop/src/stories/DefaultLayout.stories.tsx +++ b/nym-connect/desktop/src/stories/DefaultLayout.stories.tsx @@ -30,7 +30,7 @@ export const WithServices: ComponentStory = () => ( { id: '1', description: 'Keybase service', - items: [{ id: '1', description: 'Keybase service 1', gateway: 'abc123', address: '123abc' }], + items: [{ id: '1', description: 'Keybase service 1', address: '123abc' }], }, ]} clearError={() => {}} diff --git a/nym-connect/desktop/src/types/directory.ts b/nym-connect/desktop/src/types/directory.ts index 55395192a1..3883b5ce5c 100644 --- a/nym-connect/desktop/src/types/directory.ts +++ b/nym-connect/desktop/src/types/directory.ts @@ -2,7 +2,6 @@ export interface ServiceProvider { id: string; description: string; address: string; - gateway: string; } export interface Service { @@ -12,3 +11,7 @@ export interface Service { } export type Services = Service[]; + +export interface Gateway { + identity: string; +} From 290dbc1a03aad68cc857d38b1f2d1dd8690afa32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Wed, 26 Jul 2023 13:08:06 +0200 Subject: [PATCH 37/59] client-core: make latency based gateway selection concurrent (#3709) --- common/client-core/src/init/helpers.rs | 37 +++++++++++++++----------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 6ad04678f8..1c23d562f9 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -38,6 +38,7 @@ use wasm_utils::websocket::JSWebsocket; #[cfg(target_arch = "wasm32")] type WsConn = JSWebsocket; +const CONCURRENT_GATEWAYS_MEASURED: usize = 20; const MEASUREMENTS: usize = 3; #[cfg(not(target_arch = "wasm32"))] @@ -158,23 +159,29 @@ pub(super) async fn choose_gateway_by_latency( rng: &mut R, gateways: &[gateway::Node], ) -> Result { - info!("choosing gateway by latency..."); + info!( + "choosing gateway by latency, pinging {} gateways ...", + gateways.len() + ); - let mut gateways_with_latency = Vec::new(); - for gateway in gateways { - let id = *gateway.identity(); - trace!("measuring latency to {id}..."); - let with_latency = match measure_latency(gateway).await { - Ok(res) => res, - Err(err) => { - warn!("failed to measure {id}: {err}"); - continue; - } - }; - debug!("{id}: {:?}", with_latency.latency); - gateways_with_latency.push(with_latency) - } + let gateways_with_latency = Arc::new(tokio::sync::Mutex::new(Vec::new())); + futures::stream::iter(gateways) + .for_each_concurrent(CONCURRENT_GATEWAYS_MEASURED, |gateway| async { + let id = *gateway.identity(); + trace!("measuring latency to {id}..."); + match measure_latency(gateway).await { + Ok(with_latency) => { + debug!("{id}: {:?}", with_latency.latency); + gateways_with_latency.lock().await.push(with_latency); + } + Err(err) => { + warn!("failed to measure {id}: {err}"); + } + }; + }) + .await; + let gateways_with_latency = gateways_with_latency.lock().await; let chosen = gateways_with_latency .choose_weighted(rng, |item| 1. / item.latency.as_secs_f32()) .expect("invalid selection weight!"); From 516561dcf90c013993ee34cd576eb891b5b445e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 26 Jul 2023 15:49:45 +0100 Subject: [PATCH 38/59] Feature/wasm nyxd client (#3708) * separated signing and nyxd-client features * updated cosmrs to the most recent version * using tendermint_rpc directly for the Client trait * fixed rest of the codebase * removed nyxd-client feature * export more types * clippy that seems to have been skipped in makefile --- Cargo.lock | 454 ++++++++---- Cargo.toml | 6 +- clients/credential/Cargo.toml | 2 +- clients/native/Cargo.toml | 2 +- clients/webassembly/Cargo.lock | 390 +++++++--- common/bandwidth-controller/Cargo.toml | 3 +- .../bandwidth-controller/src/acquire/mod.rs | 2 +- common/client-core/Cargo.toml | 2 +- .../client-libs/validator-client/Cargo.toml | 55 +- .../examples/offline_signing.rs | 6 +- .../validator-client/src/client.rs | 32 +- .../validator-client/src/connection_tester.rs | 2 +- .../client-libs/validator-client/src/error.rs | 1 - .../client-libs/validator-client/src/lib.rs | 4 +- .../validator-client/src/nyxd/coin.rs | 13 +- .../src/nyxd/cosmwasm_client/client.rs | 109 +-- .../src/nyxd/cosmwasm_client/helpers.rs | 29 +- .../src/nyxd/cosmwasm_client/logs.rs | 3 +- .../src/nyxd/cosmwasm_client/mod.rs | 12 +- .../nyxd/cosmwasm_client/signing_client.rs | 256 ++++++- .../src/nyxd/cosmwasm_client/types.rs | 440 +----------- .../validator-client/src/nyxd/error.rs | 49 +- .../src/nyxd/fee/gas_price.rs | 6 +- .../validator-client/src/nyxd/fee/mod.rs | 8 +- .../validator-client/src/nyxd/mod.rs | 669 +++++++++--------- .../validator-client/src/nyxd/traits/mod.rs | 24 +- .../validator-client/src/signing/mod.rs | 1 - common/commands/Cargo.toml | 2 +- .../delegators/vesting_delegate_to_mixnode.rs | 2 +- .../vesting_undelegate_from_mixnode.rs | 2 +- .../gateway/settings/vesting_update_config.rs | 2 +- .../operators/gateway/vesting_bond_gateway.rs | 2 +- .../mixnode/families/create_family.rs | 2 +- .../operators/mixnode/families/join_family.rs | 2 +- .../mixnode/families/kick_family_member.rs | 2 +- .../mixnode/families/leave_family.rs | 2 +- .../mixnode/settings/vesting_update_config.rs | 2 +- .../operators/mixnode/vesting_bond_mixnode.rs | 2 +- .../mixnode/vesting_decrease_pledge.rs | 2 +- .../operators/mixnode/vesting_pledge_more.rs | 2 +- .../mixnode/vesting_unbond_mixnode.rs | 2 +- .../src/validator/signature/helpers.rs | 2 +- .../validator/transactions/get_transaction.rs | 2 +- .../commands/src/validator/vesting/balance.rs | 2 +- .../vesting/create_vesting_schedule.rs | 2 +- .../vesting/query_vesting_schedule.rs | 2 +- .../src/validator/vesting/withdraw_vested.rs | 5 +- common/credentials/src/coconut/bandwidth.rs | 11 +- common/ledger/Cargo.toml | 2 +- common/ledger/src/addr_secp256k1.rs | 2 +- common/mixnode-common/Cargo.toml | 4 +- common/socks5-client-core/Cargo.toml | 2 +- common/types/Cargo.toml | 4 +- common/types/src/gas.rs | 10 +- explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- integrations/bity/Cargo.toml | 4 +- nym-api/Cargo.toml | 2 +- nym-api/src/coconut/deposit.rs | 102 +-- nym-api/src/coconut/helpers.rs | 2 +- nym-api/src/coconut/tests.rs | 26 +- nym-api/src/support/nyxd/mod.rs | 8 +- nym-connect/desktop/Cargo.lock | 392 +++++++--- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-connect/mobile/src-tauri/Cargo.toml | 2 +- nym-wallet/Cargo.lock | 385 +++++++--- nym-wallet/nym-wallet-types/Cargo.toml | 8 +- nym-wallet/src-tauri/Cargo.toml | 10 +- nym-wallet/src-tauri/src/error.rs | 6 +- nym-wallet/src-tauri/src/main.rs | 1 - .../src-tauri/src/operations/simulate/mod.rs | 2 +- .../src-tauri/src/operations/vesting/bond.rs | 12 +- .../src/operations/vesting/delegate.rs | 2 +- .../src/operations/vesting/queries.rs | 2 +- .../src/operations/vesting/rewards.rs | 2 +- nym-wallet/src-tauri/src/utils.rs | 115 --- sdk/rust/nym-sdk/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- tools/ts-rs-cli/Cargo.toml | 2 +- 79 files changed, 2088 insertions(+), 1665 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 967762ef02..d576e05c0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -359,6 +359,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -400,13 +406,13 @@ dependencies = [ [[package]] name = "bip32" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ - "bs58", + "bs58 0.5.0", "hmac 0.12.1", - "k256", + "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -472,7 +478,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -486,7 +492,7 @@ dependencies = [ "cc", "cfg-if", "constant_time_eq", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -540,8 +546,14 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.9.9", + "sha2 0.10.6", ] [[package]] @@ -567,6 +579,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "cast" @@ -844,8 +859,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", + "prost", + "prost-types", "tonic", "tracing-core", ] @@ -862,7 +877,7 @@ dependencies = [ "futures", "hdrhistogram", "humantime 2.1.0", - "prost-types 0.11.9", + "prost-types", "serde", "serde_json", "thread_local", @@ -922,29 +937,27 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" dependencies = [ - "prost 0.10.4", - "prost-types 0.10.1", + "prost", + "prost-types", "tendermint-proto", ] [[package]] name = "cosmrs" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" +checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa", + "ecdsa 0.16.8", "eyre", "getrandom 0.2.10", - "k256", - "prost 0.10.4", - "prost-types 0.10.1", + "k256 0.13.1", "rand_core 0.6.4", "serde", "serde_json", @@ -960,9 +973,9 @@ version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", - "k256", + "k256 0.11.6", "rand_core 0.6.4", "thiserror", ] @@ -1208,6 +1221,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1330,6 +1355,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cw-controllers" version = "1.0.1" @@ -1493,6 +1531,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1557,11 +1605,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -1637,10 +1686,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.7", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -1650,7 +1713,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "serde", - "signature", + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.1.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -1660,7 +1746,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", - "ed25519", + "ed25519 1.5.3", "rand 0.7.3", "serde", "serde_bytes", @@ -1695,16 +1781,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.6", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "pkcs8", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle 2.4.1", "zeroize", ] @@ -1900,6 +2005,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "figment" version = "0.10.8" @@ -2295,6 +2410,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -2518,7 +2644,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -2975,19 +3101,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", - "sha3", ] [[package]] -name = "keccak" -version = "0.1.4" +name = "k256" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ - "cpufeatures", + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", ] [[package]] @@ -3027,7 +3157,7 @@ name = "ledger" version = "0.1.0" dependencies = [ "bip32", - "k256", + "k256 0.13.1", "ledger-transport", "ledger-transport-hid", "thiserror", @@ -3405,7 +3535,7 @@ dependencies = [ "anyhow", "async-trait", "bip39", - "bs58", + "bs58 0.4.0", "cfg-if", "clap 4.2.7", "console-subscriber", @@ -3472,7 +3602,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmrs", "cosmwasm-std", "getset", @@ -3527,7 +3657,7 @@ dependencies = [ "anyhow", "cosmrs", "eyre", - "k256", + "k256 0.13.1", "nym-cli-commands", "nym-validator-client", "serde", @@ -3542,7 +3672,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58", + "bs58 0.4.0", "clap 4.2.7", "clap_complete", "clap_complete_fig", @@ -3565,7 +3695,7 @@ version = "1.0.0" dependencies = [ "base64 0.13.1", "bip39", - "bs58", + "bs58 0.4.0", "cfg-if", "clap 4.2.7", "comfy-table", @@ -3574,7 +3704,7 @@ dependencies = [ "cw-utils", "handlebars", "humantime-serde", - "k256", + "k256 0.13.1", "log", "nym-bin-common", "nym-coconut-bandwidth-contract-common", @@ -3697,7 +3827,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "criterion", "digest 0.9.0", "doc-comment", @@ -3741,7 +3871,7 @@ dependencies = [ name = "nym-coconut-interface" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "getset", "nym-coconut", "serde", @@ -3765,7 +3895,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "schemars", "serde", @@ -3824,10 +3954,10 @@ version = "0.4.0" dependencies = [ "aes 0.8.2", "blake3", - "bs58", + "bs58 0.4.0", "cipher 0.4.4", "ctr 0.9.2", - "digest 0.10.6", + "digest 0.10.7", "ed25519-dalek", "generic-array 0.14.7", "hkdf 0.12.3", @@ -3850,7 +3980,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "criterion", "ff 0.11.1", "group 0.11.0", @@ -3883,7 +4013,7 @@ dependencies = [ "async-trait", "atty", "bip39", - "bs58", + "bs58 0.4.0", "clap 4.2.7", "colored", "dashmap 4.0.2", @@ -3960,7 +4090,7 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "futures", "generic-array 0.14.7", "log", @@ -4013,7 +4143,7 @@ dependencies = [ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "humantime-serde", "log", @@ -4033,7 +4163,7 @@ name = "nym-mixnode" version = "1.1.24" dependencies = [ "anyhow", - "bs58", + "bs58 0.4.0", "cfg-if", "clap 4.2.7", "colored", @@ -4151,7 +4281,7 @@ dependencies = [ "anyhow", "async-file-watcher", "async-trait", - "bs58", + "bs58 0.4.0", "clap 4.2.7", "dirs 4.0.0", "futures", @@ -4515,7 +4645,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -4654,7 +4784,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58", + "bs58 0.4.0", "log", "nym-bin-common", "nym-crypto", @@ -4724,11 +4854,12 @@ dependencies = [ "nym-vesting-contract", "nym-vesting-contract-common", "openssl", - "prost 0.10.4", + "prost", "reqwest", "serde", "serde_json", "sha2 0.9.9", + "tendermint-rpc", "thiserror", "tokio", "ts-rs", @@ -5084,11 +5215,12 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -5240,8 +5372,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.7", + "spki 0.7.2", ] [[package]] @@ -5402,16 +5544,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "prost" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" -dependencies = [ - "bytes", - "prost-derive 0.10.1", -] - [[package]] name = "prost" version = "0.11.9" @@ -5419,20 +5551,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost-derive" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.109", + "prost-derive", ] [[package]] @@ -5448,23 +5567,13 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "prost-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" -dependencies = [ - "bytes", - "prost 0.10.4", -] - [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "prost 0.11.9", + "prost", ] [[package]] @@ -5866,11 +5975,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + [[package]] name = "ring" version = "0.16.20" @@ -5892,18 +6011,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest 0.10.7", ] [[package]] @@ -6233,10 +6341,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.7", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle 2.4.1", "zeroize", ] @@ -6436,7 +6558,7 @@ checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -6447,7 +6569,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -6471,17 +6593,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.6", - "keccak", + "digest 0.10.7", ] [[package]] @@ -6529,7 +6641,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -6600,7 +6722,7 @@ dependencies = [ "aes 0.7.5", "arrayref", "blake2 0.8.1", - "bs58", + "bs58 0.4.0", "byteorder", "chacha", "curve25519-dalek", @@ -6637,7 +6759,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.7", ] [[package]] @@ -6937,6 +7069,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.109" @@ -7001,28 +7139,28 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" +checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ - "async-trait", "bytes", - "ed25519", - "ed25519-dalek", + "digest 0.10.7", + "ed25519 2.2.1", + "ed25519-consensus", "flex-error", "futures", - "k256", + "k256 0.13.1", "num-traits", "once_cell", - "prost 0.10.4", - "prost-types 0.10.1", - "ripemd160", + "prost", + "prost-types", + "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.9.9", - "signature", + "sha2 0.10.6", + "signature 2.1.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -7032,9 +7170,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" +checksum = "71a72dbbea6dde12045d261f2c70c0de039125675e8a026c8d5ad34522756372" dependencies = [ "flex-error", "serde", @@ -7046,16 +7184,16 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" dependencies = [ "bytes", "flex-error", "num-derive", "num-traits", - "prost 0.10.4", - "prost-types 0.10.1", + "prost", + "prost-types", "serde", "serde_bytes", "subtle-encoding", @@ -7064,9 +7202,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.8" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" +checksum = "bd2cc789170db5a35d4e0bb2490035c03ef96df08f119bee25fd8dab5a09aa25" dependencies = [ "async-trait", "bytes", @@ -7079,9 +7217,11 @@ dependencies = [ "hyper-rustls", "peg", "pin-project", + "semver 1.0.17", "serde", "serde_bytes", "serde_json", + "subtle 2.4.1", "subtle-encoding", "tendermint", "tendermint-config", @@ -7438,7 +7578,7 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.11.9", + "prost", "tokio", "tokio-stream", "tower", diff --git a/Cargo.toml b/Cargo.toml index 8e40379227..fd137c6bdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,7 +121,9 @@ cosmwasm-derive = "=1.2.5" cosmwasm-schema = "=1.2.5" cosmwasm-std = "=1.2.5" cosmwasm-storage = "=1.2.5" -cosmrs = "=0.8.0" +cosmrs = "=0.14.0" +# same version as used by cosmrs +tendermint-rpc = "=0.32" cw-utils = "=1.0.1" cw-storage-plus = "=1.0.1" cw2 = { version = "=1.0.1" } @@ -131,7 +133,7 @@ cw4 = { version = "=1.0.1" } cw-controllers = { version = "=1.0.1" } dotenvy = "0.15.6" generic-array = "0.14.7" -k256 = "0.11" +k256 = "0.13" getrandom = "0.2.10" lazy_static = "1.4.0" log = "0.4" diff --git a/clients/credential/Cargo.toml b/clients/credential/Cargo.toml index 8d161359ec..8ceb14bc98 100644 --- a/clients/credential/Cargo.toml +++ b/clients/credential/Cargo.toml @@ -21,5 +21,5 @@ nym-credential-storage = { path = "../../common/credential-storage" } nym-bin-common = { path = "../../common/bin-common"} nym-network-defaults = { path = "../../common/network-defaults" } nym-pemstore = { path = "../../common/pemstore" } -nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../../common/client-libs/validator-client" } diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 0be4139630..6064304a90 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -48,7 +48,7 @@ nym-sphinx = { path = "../../common/nymsphinx" } nym-pemstore = { path = "../../common/pemstore" } nym-task = { path = "../../common/task" } nym-topology = { path = "../../common/topology" } -nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] } nym-client-websocket-requests = { path = "websocket-requests" } [dev-dependencies] diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index ceef50ba14..f0733eac1b 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -217,6 +217,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -237,13 +243,13 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bip32" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ - "bs58", + "bs58 0.5.0", "hmac 0.12.1", - "k256", + "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -309,7 +315,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -323,7 +329,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "constant_time_eq", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -377,8 +383,14 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.9.9", + "sha2 0.10.6", ] [[package]] @@ -404,6 +416,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "cc" @@ -598,9 +613,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" dependencies = [ "prost", "prost-types", @@ -609,18 +624,16 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" +checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa", + "ecdsa 0.16.8", "eyre", "getrandom 0.2.10", - "k256", - "prost", - "prost-types", + "k256 0.13.1", "rand_core 0.6.4", "serde", "serde_json", @@ -636,9 +649,9 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", - "k256", + "k256 0.11.6", "rand_core 0.6.4", "thiserror", ] @@ -815,6 +828,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -887,6 +912,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cw-controllers" version = "1.0.1" @@ -1005,6 +1043,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1036,11 +1084,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -1110,10 +1159,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.7", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -1123,7 +1186,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "serde", - "signature", + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.1.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -1133,7 +1219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", - "ed25519", + "ed25519 1.5.3", "rand 0.7.3", "serde", "serde_bytes", @@ -1168,16 +1254,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.6", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "pkcs8", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle 2.4.1", "zeroize", ] @@ -1300,6 +1405,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "flate2" version = "1.0.26" @@ -1603,6 +1718,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "h2" version = "0.3.19" @@ -1786,7 +1912,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -2062,19 +2188,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if 1.0.0", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", - "sha3", ] [[package]] -name = "keccak" -version = "0.1.4" +name = "k256" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ - "cpufeatures", + "cfg-if 1.0.0", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", ] [[package]] @@ -2290,7 +2420,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmrs", "cosmwasm-std", "getset", @@ -2382,7 +2512,7 @@ version = "1.1.1" dependencies = [ "anyhow", "async-trait", - "bs58", + "bs58 0.4.0", "console_error_panic_hook", "futures", "js-sys", @@ -2420,7 +2550,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "digest 0.9.0", "ff 0.11.1", "getrandom 0.2.10", @@ -2461,7 +2591,7 @@ dependencies = [ name = "nym-coconut-interface" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "getset", "nym-coconut", "serde", @@ -2485,7 +2615,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "schemars", "serde", @@ -2522,10 +2652,10 @@ version = "0.4.0" dependencies = [ "aes 0.8.2", "blake3", - "bs58", + "bs58 0.4.0", "cipher 0.4.4", "ctr 0.9.2", - "digest 0.10.6", + "digest 0.10.7", "ed25519-dalek", "generic-array 0.14.7", "hkdf 0.12.3", @@ -2547,7 +2677,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "ff 0.11.1", "group 0.11.0", "lazy_static", @@ -2597,7 +2727,7 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "futures", "generic-array 0.14.7", "log", @@ -2629,7 +2759,7 @@ dependencies = [ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "humantime-serde", "log", @@ -2806,7 +2936,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -2930,7 +3060,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58", + "bs58 0.4.0", "log", "nym-bin-common", "nym-crypto", @@ -2979,6 +3109,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.9.9", + "tendermint-rpc", "thiserror", "tokio", "url", @@ -3167,11 +3298,12 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -3300,8 +3432,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.7", + "spki 0.7.2", ] [[package]] @@ -3384,9 +3526,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.10.4" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", @@ -3394,9 +3536,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", @@ -3407,11 +3549,10 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes", "prost", ] @@ -3634,11 +3775,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + [[package]] name = "ring" version = "0.16.20" @@ -3660,18 +3811,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest 0.10.7", ] [[package]] @@ -3836,10 +3976,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.7", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle 2.4.1", "zeroize", ] @@ -4024,7 +4178,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -4048,17 +4202,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.6", - "keccak", + "digest 0.10.7", ] [[package]] @@ -4076,7 +4220,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -4114,7 +4268,7 @@ dependencies = [ "aes 0.7.5", "arrayref", "blake2 0.8.1", - "bs58", + "bs58 0.4.0", "byteorder", "chacha", "curve25519-dalek", @@ -4151,7 +4305,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.7", ] [[package]] @@ -4390,6 +4554,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.109" @@ -4433,28 +4603,28 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" +checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ - "async-trait", "bytes", - "ed25519", - "ed25519-dalek", + "digest 0.10.7", + "ed25519 2.2.1", + "ed25519-consensus", "flex-error", "futures", - "k256", + "k256 0.13.1", "num-traits", "once_cell", "prost", "prost-types", - "ripemd160", + "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.9.9", - "signature", + "sha2 0.10.6", + "signature 2.1.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -4464,9 +4634,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" +checksum = "71a72dbbea6dde12045d261f2c70c0de039125675e8a026c8d5ad34522756372" dependencies = [ "flex-error", "serde", @@ -4478,9 +4648,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" dependencies = [ "bytes", "flex-error", @@ -4496,9 +4666,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" +checksum = "d119d83a130537fc4a98c3c9eb6899ebe857fea4860400a61675bfb5f0b35129" dependencies = [ "async-trait", "bytes", @@ -4511,9 +4681,11 @@ dependencies = [ "hyper-rustls", "peg", "pin-project", + "semver 1.0.17", "serde", "serde_bytes", "serde_json", + "subtle 2.4.1", "subtle-encoding", "tendermint", "tendermint-config", diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 40fe146d81..5b168d8b9f 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -18,7 +18,6 @@ nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric" nym-network-defaults = { path = "../network-defaults" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } - [target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] path = "../client-libs/validator-client" -features = ["nyxd-client"] +features = ["signing"] diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index cfaf8dc473..cdf72c3b00 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -10,8 +10,8 @@ use nym_crypto::asymmetric::{encryption, identity}; use nym_network_defaults::VOUCHER_INFO; use nym_validator_client::nyxd::traits::CoconutBandwidthSigningClient; use nym_validator_client::nyxd::traits::DkgQueryClient; -use nym_validator_client::nyxd::tx::Hash; use nym_validator_client::nyxd::Coin; +use nym_validator_client::nyxd::Hash; use nym_validator_client::CoconutApiClient; use rand::rngs::OsRng; use state::{KeyPair, State}; diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index b8b1403d86..d5ae32dbd2 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -45,7 +45,7 @@ nym-network-defaults = { path = "../network-defaults" } [target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] path = "../client-libs/validator-client" -features = ["nyxd-client"] +features = ["signing", "http-client"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index ac66916c46..31475887bc 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -35,27 +35,30 @@ nym-coconut-interface = { path = "../../coconut-interface" } nym-network-defaults = { path = "../../network-defaults" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } -# required for nyxd-client -# at some point it might be possible to make it wasm-compatible -# perhaps after https://github.com/cosmos/cosmos-rust/pull/97 is resolved (and tendermint-rs is updated) -async-trait = { workspace = true, optional = true } +async-trait = { workspace = true } bip39 = { workspace = true, features = ["rand"], optional = true } -nym-config = { path = "../../config", optional = true } -cosmrs = { workspace = true, features = ["rpc", "bip32", "cosmwasm"], optional = true } +nym-config = { path = "../../config" } +cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] } +#cosmrs = { workspace = true, features = ["bip32", "rpc", "cosmwasm"], optional = true } # note that this has the same version as used by cosmrs + +# import it just for the `Client` trait +tendermint-rpc = { workspace = true } + eyre = { version = "0.6", optional = true } -cw3 = { workspace = true, optional = true } -cw4 = { workspace = true, optional = true } -prost = { version = "0.10", default-features = false, optional = true } -flate2 = { version = "1.0.20", optional = true } -sha2 = { version = "0.9.5", optional = true } -itertools = { version = "0.10", optional = true } +cw3 = { workspace = true } +cw4 = { workspace = true } +prost = { version = "0.11", default-features = false } +flate2 = { version = "1.0.20" } +sha2 = { version = "0.9.5" } +itertools = { version = "0.10" } zeroize = { version = "1.5.7", optional = true, features = ["zeroize_derive"] } -cosmwasm-std = { workspace = true, optional = true } +cosmwasm-std = { workspace = true } [dev-dependencies] bip39 = { workspace = true } -cosmrs = { workspace = true, features = ["rpc", "bip32"] } +#cosmrs = { workspace = true, features = ["rpc", "bip32"] } +cosmrs = { workspace = true, features = ["bip32"] } tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } ts-rs = "6.1.2" @@ -64,35 +67,23 @@ name = "offline_signing" # it should only really require the "signing" feature, # but that would require another round of refactoring to make it possible # (traits would need to be moved around and refactored themselves) -required-features = ["nyxd-client"] +required-features = ["http-client", "signing"] [[example]] name = "query_service_provider_directory" -required-features = ["nyxd-client"] +# TODO: validate the requirements +required-features = ["http-client", "signing"] [[example]] name = "query_name_service" -required-features = ["nyxd-client"] +# TODO: validate the requirements +required-features = ["http-client", "signing"] [features] -nyxd-client = [ - "async-trait", - "cosmrs", - "cosmwasm-std", - "cw3", - "cw4", - "flate2", - "itertools", - "openssl", - "prost", - "sha2", - "signing" -] +http-client = ["cosmrs/rpc", "openssl"] signing = [ "bip39", - "cosmrs", "eyre", - "nym-config", "zeroize" ] generate-ts = [] diff --git a/common/client-libs/validator-client/examples/offline_signing.rs b/common/client-libs/validator-client/examples/offline_signing.rs index d48db60e53..a21bfa4475 100644 --- a/common/client-libs/validator-client/examples/offline_signing.rs +++ b/common/client-libs/validator-client/examples/offline_signing.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use cosmrs::bank::MsgSend; -use cosmrs::rpc::{self, HttpClient}; +use cosmrs::rpc::HttpClient; use cosmrs::tx::Msg; use cosmrs::{tx, AccountId, Coin, Denom}; use nym_validator_client::nyxd::CosmWasmClient; @@ -54,7 +54,7 @@ async fn main() { denom, amount: 2500u32.into(), }, - 100000, + 100000u32, ); let tx_raw = tx_signer @@ -70,7 +70,7 @@ async fn main() { .unwrap(); // broadcast the tx - let res = rpc::Client::broadcast_tx_commit(&broadcaster, tx_bytes.into()) + let res = tendermint_rpc::client::Client::broadcast_tx_commit(&broadcaster, tx_bytes) .await .unwrap(); diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 1ccf62a67e..54539403fb 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -16,37 +16,35 @@ pub use nym_mixnet_contract_common::{ }; use url::Url; -#[cfg(feature = "nyxd-client")] use crate::nyxd::traits::{DkgQueryClient, MixnetQueryClient}; -#[cfg(feature = "nyxd-client")] -use crate::nyxd::{self, CosmWasmClient, NyxdClient, QueryNyxdClient, SigningNyxdClient}; -#[cfg(feature = "nyxd-client")] -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; -#[cfg(feature = "nyxd-client")] +#[cfg(feature = "http-client")] +use crate::nyxd::QueryNyxdClient; +use crate::nyxd::{self, CosmWasmClient, NyxdClient}; use nym_api_requests::models::MixNodeBondAnnotated; -#[cfg(feature = "nyxd-client")] use nym_coconut_dkg_common::{types::EpochId, verification_key::ContractVKShare}; -#[cfg(feature = "nyxd-client")] use nym_coconut_interface::Base58; -#[cfg(feature = "nyxd-client")] use nym_mixnet_contract_common::{ families::{Family, FamilyHead}, mixnode::MixNodeBond, pending_events::{PendingEpochEvent, PendingIntervalEvent}, Delegation, RewardedSetNodeStatus, UnbondedMixnode, }; -#[cfg(feature = "nyxd-client")] use nym_network_defaults::NymNetworkDetails; -#[cfg(feature = "nyxd-client")] use std::str::FromStr; -#[cfg(feature = "nyxd-client")] +#[cfg(all(feature = "signing", feature = "http-client"))] +use crate::nyxd::SigningNyxdClient; +#[cfg(all(feature = "signing", feature = "http-client"))] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; + #[must_use] #[derive(Debug, Clone)] pub struct Config { api_url: Url, nyxd_url: Url, + // TODO: until refactored, this is a dead field under some features + #[allow(dead_code)] nyxd_config: nyxd::Config, mixnode_page_limit: Option, @@ -55,7 +53,6 @@ pub struct Config { rewarded_set_page_limit: Option, } -#[cfg(feature = "nyxd-client")] impl Config { pub fn try_from_nym_network_details( details: &NymNetworkDetails, @@ -119,7 +116,6 @@ impl Config { } } -#[cfg(feature = "nyxd-client")] pub struct Client { mixnode_page_limit: Option, gateway_page_limit: Option, @@ -131,7 +127,7 @@ pub struct Client { pub nyxd: NyxdClient, } -#[cfg(feature = "nyxd-client")] +#[cfg(all(feature = "signing", feature = "http-client"))] impl Client> { pub fn new_signing( config: Config, @@ -165,7 +161,7 @@ impl Client> { } } -#[cfg(feature = "nyxd-client")] +#[cfg(feature = "http-client")] impl Client { pub fn new_query(config: Config) -> Result, ValidatorClientError> { let nym_api_client = nym_api::Client::new(config.api_url.clone()); @@ -189,7 +185,6 @@ impl Client { } // nyxd wrappers -#[cfg(feature = "nyxd-client")] impl Client { // use case: somebody initialised client without a contract in order to upload and initialise one // and now they want to actually use it without making new client @@ -572,7 +567,6 @@ impl Client { } // validator-api wrappers -#[cfg(feature = "nyxd-client")] impl Client { pub fn change_nym_api(&mut self, new_endpoint: Url) { self.nym_api.change_url(new_endpoint) @@ -635,11 +629,9 @@ pub struct CoconutApiClient { pub api_client: NymApiClient, pub verification_key: VerificationKey, pub node_id: NodeIndex, - #[cfg(feature = "nyxd-client")] pub cosmos_address: cosmrs::AccountId, } -#[cfg(feature = "nyxd-client")] impl CoconutApiClient { pub async fn all_coconut_api_clients( client: &C, diff --git a/common/client-libs/validator-client/src/connection_tester.rs b/common/client-libs/validator-client/src/connection_tester.rs index 5d89e86d05..800399d415 100644 --- a/common/client-libs/validator-client/src/connection_tester.rs +++ b/common/client-libs/validator-client/src/connection_tester.rs @@ -120,7 +120,7 @@ async fn test_nyxd_connection( ) .await { - Ok(Err(NyxdError::TendermintError(e))) => { + Ok(Err(NyxdError::TendermintErrorRpc(e))) => { // If we get a tendermint-rpc error, we classify the node as not contactable log::warn!("Checking: nyxd url: {url}: {}: {}", "failed".red(), e); false diff --git a/common/client-libs/validator-client/src/error.rs b/common/client-libs/validator-client/src/error.rs index 08da52c626..a675a27717 100644 --- a/common/client-libs/validator-client/src/error.rs +++ b/common/client-libs/validator-client/src/error.rs @@ -15,7 +15,6 @@ pub enum ValidatorClientError { #[error("One of the provided URLs was malformed - {0}")] MalformedUrlProvided(#[from] url::ParseError), - #[cfg(feature = "nyxd-client")] #[error("nyxd request failed - {0}")] NyxdError(#[from] crate::nyxd::error::NyxdError), diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index 5d18c251c0..ab0cff646e 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -2,11 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 pub mod client; -#[cfg(feature = "nyxd-client")] +#[cfg(feature = "http-client")] pub mod connection_tester; pub mod error; pub mod nym_api; -#[cfg(feature = "nyxd-client")] pub mod nyxd; #[cfg(feature = "signing")] @@ -16,5 +15,4 @@ pub use crate::error::ValidatorClientError; pub use client::NymApiClient; pub use nym_api_requests::*; -#[cfg(feature = "nyxd-client")] pub use client::{Client, CoconutApiClient, Config}; diff --git a/common/client-libs/validator-client/src/nyxd/coin.rs b/common/client-libs/validator-client/src/nyxd/coin.rs index 3ac51997b8..f780bd32f3 100644 --- a/common/client-libs/validator-client/src/nyxd/coin.rs +++ b/common/client-libs/validator-client/src/nyxd/coin.rs @@ -52,7 +52,6 @@ impl<'a> Div for &'a Coin { } else { implicit_gas_limit.u128() as u64 } - .into() } } @@ -191,32 +190,32 @@ mod tests { let amount = Coin::new(3938, "unym"); let gas_price = "0.025unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(157520, res.value()); + assert_eq!(157520, res); let amount = Coin::new(1234567890, "unym"); let gas_price = "0.025unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(49382715600, res.value()); + assert_eq!(49382715600, res); let amount = Coin::new(1, "unym"); let gas_price = "0.025unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(40, res.value()); + assert_eq!(40, res); let amount = Coin::new(150_000_000, "unym"); let gas_price = "0.001234unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(121555915721, res.value()); + assert_eq!(121555915721, res); let amount = Coin::new(150_000_000, "unym"); let gas_price = "1unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(150_000_000, res.value()); + assert_eq!(150_000_000, res); let amount = Coin::new(150_000_000, "unym"); let gas_price = "1234.56unym".parse().unwrap(); let res = amount / gas_price; - assert_eq!(121500, res.value()); + assert_eq!(121500, res); } #[test] diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs index 9be833c68b..4a512a02db 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs @@ -1,15 +1,16 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::nyxd; use crate::nyxd::coin::Coin; use crate::nyxd::cosmwasm_client::helpers::{create_pagination, next_page_key}; use crate::nyxd::cosmwasm_client::types::{ - Account, Code, CodeDetails, Contract, ContractCodeHistoryEntry, ContractCodeId, - SequenceResponse, SimulateResponse, + Account, CodeDetails, Contract, ContractCodeId, SequenceResponse, SimulateResponse, }; use crate::nyxd::error::NyxdError; +use crate::nyxd::TendermintClient; use async_trait::async_trait; +use cosmrs::cosmwasm::{CodeInfoResponse, ContractCodeHistoryEntry}; use cosmrs::proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; use cosmrs::proto::cosmos::bank::v1beta1::{ QueryAllBalancesRequest, QueryAllBalancesResponse, QueryBalanceRequest, QueryBalanceResponse, @@ -18,22 +19,28 @@ use cosmrs::proto::cosmos::bank::v1beta1::{ use cosmrs::proto::cosmos::tx::v1beta1::{ SimulateRequest, SimulateResponse as ProtoSimulateResponse, }; -use cosmrs::proto::cosmwasm::wasm::v1::*; -use cosmrs::rpc::endpoint::block::Response as BlockResponse; -use cosmrs::rpc::endpoint::broadcast; -use cosmrs::rpc::endpoint::tx::Response as TxResponse; -use cosmrs::rpc::query::Query; -use cosmrs::rpc::{self, HttpClient, Order}; -use cosmrs::tendermint::abci::Transaction; -use cosmrs::tendermint::{abci, block, chain}; -use cosmrs::{tx, AccountId, Coin as CosmosCoin, Tx}; +use cosmrs::proto::cosmwasm::wasm::v1::{ + QueryCodeRequest, QueryCodeResponse, QueryCodesRequest, QueryCodesResponse, + QueryContractHistoryRequest, QueryContractHistoryResponse, QueryContractInfoRequest, + QueryContractInfoResponse, QueryContractsByCodeRequest, QueryContractsByCodeResponse, + QueryRawContractStateRequest, QueryRawContractStateResponse, QuerySmartContractStateRequest, + QuerySmartContractStateResponse, +}; +use cosmrs::tendermint::{block, chain, Hash}; +use cosmrs::{AccountId, Coin as CosmosCoin, Tx}; use prost::Message; use serde::{Deserialize, Serialize}; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; use std::time::Duration; +use tendermint_rpc::{ + endpoint::{block::Response as BlockResponse, broadcast, tx::Response as TxResponse}, + query::Query, + Order, +}; +#[cfg(feature = "http-client")] #[async_trait] -impl CosmWasmClient for HttpClient { +impl CosmWasmClient for cosmrs::rpc::HttpClient { fn broadcast_polling_rate(&self) -> Duration { Duration::from_secs(4) } @@ -44,7 +51,7 @@ impl CosmWasmClient for HttpClient { } #[async_trait] -pub trait CosmWasmClient: rpc::Client { +pub trait CosmWasmClient: TendermintClient { // this should probably get redesigned, but I'm leaving those like that temporarily to fix // the underlying issue more quickly fn broadcast_polling_rate(&self) -> Duration; @@ -55,7 +62,7 @@ pub trait CosmWasmClient: rpc::Client { // require proof? async fn make_abci_query( &self, - path: Option, + path: Option, req: Req, ) -> Result where @@ -81,7 +88,7 @@ pub trait CosmWasmClient: rpc::Client { // TODO: the return type should probably be changed to a non-proto, type-safe Account alternative async fn get_account(&self, address: &AccountId) -> Result, NyxdError> { - let path = Some("/cosmos.auth.v1beta1.Query/Account".parse().unwrap()); + let path = Some("/cosmos.auth.v1beta1.Query/Account".to_owned()); let req = QueryAccountRequest { address: address.to_string(), @@ -119,7 +126,7 @@ pub trait CosmWasmClient: rpc::Client { address: &AccountId, search_denom: String, ) -> Result, NyxdError> { - let path = Some("/cosmos.bank.v1beta1.Query/Balance".parse().unwrap()); + let path = Some("/cosmos.bank.v1beta1.Query/Balance".to_owned()); let req = QueryBalanceRequest { address: address.to_string(), @@ -137,7 +144,7 @@ pub trait CosmWasmClient: rpc::Client { } async fn get_all_balances(&self, address: &AccountId) -> Result, NyxdError> { - let path = Some("/cosmos.bank.v1beta1.Query/AllBalances".parse().unwrap()); + let path = Some("/cosmos.bank.v1beta1.Query/AllBalances".to_owned()); let mut raw_balances = Vec::new(); let mut pagination = None; @@ -168,7 +175,7 @@ pub trait CosmWasmClient: rpc::Client { } async fn get_total_supply(&self) -> Result, NyxdError> { - let path = Some("/cosmos.bank.v1beta1.Query/TotalSupply".parse().unwrap()); + let path = Some("/cosmos.bank.v1beta1.Query/TotalSupply".to_owned()); let mut supply = Vec::new(); let mut pagination = None; @@ -195,7 +202,7 @@ pub trait CosmWasmClient: rpc::Client { .map_err(|_| NyxdError::SerializationError("Coins".to_owned())) } - async fn get_tx(&self, id: tx::Hash) -> Result { + async fn get_tx(&self, id: Hash) -> Result { Ok(self.tx(id, false).await?) } @@ -231,30 +238,36 @@ pub trait CosmWasmClient: rpc::Client { } /// Broadcast a transaction, returning immediately. - async fn broadcast_tx_async( - &self, - tx: Transaction, - ) -> Result { - Ok(rpc::Client::broadcast_tx_async(self, tx).await?) + async fn broadcast_tx_async(&self, tx: T) -> Result + where + T: Into> + Send, + { + Ok(tendermint_rpc::client::Client::broadcast_tx_async(self, tx).await?) } /// Broadcast a transaction, returning the response from `CheckTx`. - async fn broadcast_tx_sync( - &self, - tx: Transaction, - ) -> Result { - Ok(rpc::Client::broadcast_tx_sync(self, tx).await?) + async fn broadcast_tx_sync(&self, tx: T) -> Result + where + T: Into> + Send, + { + Ok(tendermint_rpc::client::Client::broadcast_tx_sync(self, tx).await?) } /// Broadcast a transaction, returning the response from `DeliverTx`. - async fn broadcast_tx_commit( + async fn broadcast_tx_commit( &self, - tx: Transaction, - ) -> Result { - Ok(rpc::Client::broadcast_tx_commit(self, tx).await?) + tx: T, + ) -> Result + where + T: Into> + Send, + { + Ok(tendermint_rpc::client::Client::broadcast_tx_commit(self, tx).await?) } - async fn broadcast_tx(&self, tx: Transaction) -> Result { + async fn broadcast_tx(&self, tx: T) -> Result + where + T: Into> + Send, + { let broadcasted = CosmWasmClient::broadcast_tx_sync(self, tx).await?; if broadcasted.code.is_err() { @@ -290,8 +303,8 @@ pub trait CosmWasmClient: rpc::Client { } } - async fn get_codes(&self) -> Result, NyxdError> { - let path = Some("/cosmwasm.wasm.v1.Query/Codes".parse().unwrap()); + async fn get_codes(&self) -> Result, NyxdError> { + let path = Some("/cosmwasm.wasm.v1.Query/Codes".to_owned()); let mut raw_codes = Vec::new(); let mut pagination = None; @@ -311,14 +324,14 @@ pub trait CosmWasmClient: rpc::Client { } } - raw_codes + Ok(raw_codes .into_iter() .map(TryFrom::try_from) - .collect::>() + .collect::>()?) } async fn get_code_details(&self, code_id: ContractCodeId) -> Result { - let path = Some("/cosmwasm.wasm.v1.Query/Code".parse().unwrap()); + let path = Some("/cosmwasm.wasm.v1.Query/Code".to_owned()); let req = QueryCodeRequest { code_id }; @@ -333,7 +346,7 @@ pub trait CosmWasmClient: rpc::Client { } } async fn get_contracts(&self, code_id: ContractCodeId) -> Result, NyxdError> { - let path = Some("/cosmwasm.wasm.v1.Query/ContractsByCode".parse().unwrap()); + let path = Some("/cosmwasm.wasm.v1.Query/ContractsByCode".to_owned()); let mut raw_contracts = Vec::new(); let mut pagination = None; @@ -364,7 +377,7 @@ pub trait CosmWasmClient: rpc::Client { } async fn get_contract(&self, address: &AccountId) -> Result { - let path = Some("/cosmwasm.wasm.v1.Query/ContractInfo".parse().unwrap()); + let path = Some("/cosmwasm.wasm.v1.Query/ContractInfo".to_owned()); let req = QueryContractInfoRequest { address: address.to_string(), @@ -389,7 +402,7 @@ pub trait CosmWasmClient: rpc::Client { &self, address: &AccountId, ) -> Result, NyxdError> { - let path = Some("/cosmwasm.wasm.v1.Query/ContractHistory".parse().unwrap()); + let path = Some("/cosmwasm.wasm.v1.Query/ContractHistory".to_owned()); let mut raw_entries = Vec::new(); let mut pagination = None; @@ -412,10 +425,10 @@ pub trait CosmWasmClient: rpc::Client { } } - raw_entries + Ok(raw_entries .into_iter() .map(TryFrom::try_from) - .collect::>() + .collect::>()?) } async fn query_contract_raw( @@ -423,7 +436,7 @@ pub trait CosmWasmClient: rpc::Client { address: &AccountId, query_data: Vec, ) -> Result, NyxdError> { - let path = Some("/cosmwasm.wasm.v1.Query/RawContractState".parse().unwrap()); + let path = Some("/cosmwasm.wasm.v1.Query/RawContractState".to_owned()); let req = QueryRawContractStateRequest { address: address.to_string(), @@ -479,7 +492,7 @@ pub trait CosmWasmClient: rpc::Client { tx: Option, tx_bytes: Vec, ) -> Result { - let path = Some("/cosmos.tx.v1beta1.Service/Simulate".parse().unwrap()); + let path = Some("/cosmos.tx.v1beta1.Service/Simulate".to_owned()); let req = SimulateRequest { tx: tx.map(Into::into), diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs index 0dd7f98ead..64c2fd25fa 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs @@ -3,12 +3,7 @@ use crate::nyxd::error::NyxdError; use cosmrs::proto::cosmos::base::query::v1beta1::{PageRequest, PageResponse}; -use cosmrs::proto::cosmos::base::v1beta1::Coin as ProtoCoin; -use cosmrs::rpc::endpoint::broadcast; -use cosmrs::Coin; -use flate2::write::GzEncoder; -use flate2::Compression; -use std::io::Write; +use tendermint_rpc::endpoint::broadcast; pub(crate) trait CheckResponse: Sized { fn check_response(self) -> Result; @@ -21,7 +16,7 @@ impl CheckResponse for broadcast::tx_commit::Response { hash: self.hash, height: Some(self.height), code: self.check_tx.code.value(), - raw_log: self.check_tx.log.value().to_owned(), + raw_log: self.check_tx.log, }); } @@ -30,7 +25,7 @@ impl CheckResponse for broadcast::tx_commit::Response { hash: self.hash, height: Some(self.height), code: self.deliver_tx.code.value(), - raw_log: self.deliver_tx.log.value().to_owned(), + raw_log: self.deliver_tx.log, }); } @@ -45,7 +40,7 @@ impl CheckResponse for crate::nyxd::TxResponse { hash: self.hash, height: Some(self.height), code: self.tx_result.code.value(), - raw_log: self.tx_result.log.value().to_owned(), + raw_log: self.tx_result.log, }); } @@ -53,7 +48,12 @@ impl CheckResponse for crate::nyxd::TxResponse { } } +#[cfg(feature = "signing")] pub(crate) fn compress_wasm_code(code: &[u8]) -> Result, NyxdError> { + use flate2::write::GzEncoder; + use flate2::Compression; + use std::io::Write; + // using compression level 9, same as cosmjs, that optimises for size let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); encoder @@ -83,14 +83,3 @@ pub(crate) fn next_page_key(pagination_info: Option) -> Option) -> Result, NyxdError> { - value - .into_iter() - .map(|proto_coin| { - Coin::try_from(&proto_coin).map_err(|_| NyxdError::MalformedCoin { - coin_representation: format!("{:?}", proto_coin), - }) - }) - .collect() -} diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/logs.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/logs.rs index 3912500f47..d16b3055c2 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/logs.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/logs.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::error::NyxdError; -use cosmrs::tendermint::abci; use itertools::Itertools; use serde::{Deserialize, Serialize}; @@ -49,7 +48,7 @@ fn parse_raw_str_logs(raw: &str) -> Result, NyxdError> { Ok(logs) } -pub fn parse_raw_logs(raw: abci::Log) -> Result, NyxdError> { +pub fn parse_raw_logs(raw: String) -> Result, NyxdError> { parse_raw_str_logs(raw.as_ref()) } diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs index f668cc27a1..0a2d2c7c32 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs @@ -1,17 +1,22 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +#[cfg(feature = "http-client")] use crate::nyxd::error::NyxdError; -use crate::nyxd::GasPrice; +#[cfg(feature = "http-client")] use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl}; +#[cfg(feature = "http-client")] use std::convert::TryInto; pub mod client; mod helpers; pub mod logs; -pub mod signing_client; pub mod types; +#[cfg(feature = "signing")] +pub mod signing_client; + +#[cfg(feature = "http-client")] pub fn connect(endpoint: U) -> Result where U: TryInto, @@ -19,10 +24,11 @@ where Ok(HttpClient::new(endpoint)?) } +#[cfg(all(feature = "signing", feature = "http-client"))] pub fn connect_with_signer( endpoint: U, signer: S, - gas_price: GasPrice, + gas_price: crate::nyxd::GasPrice, ) -> Result, NyxdError> where U: TryInto, diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs index 88919743cd..f4d6a41829 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs @@ -9,29 +9,37 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::fee::{Fee, DEFAULT_SIMULATED_GAS_MULTIPLIER}; use crate::nyxd::{Coin, GasAdjustable, GasPrice, TxResponse}; use crate::signing::signer::OfflineSigner; -use crate::signing::tx_signer::TxSigner; use crate::signing::SignerData; use async_trait::async_trait; +use cosmrs::abci::GasInfo; use cosmrs::bank::MsgSend; use cosmrs::distribution::MsgWithdrawDelegatorReward; use cosmrs::feegrant::{ AllowedMsgAllowance, BasicAllowance, MsgGrantAllowance, MsgRevokeAllowance, }; use cosmrs::proto::cosmos::tx::signing::v1beta1::SignMode; -use cosmrs::rpc::endpoint::broadcast; -use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl, SimpleRequest}; use cosmrs::staking::{MsgDelegate, MsgUndelegate}; -use cosmrs::tx::{self, Msg, Raw}; -use cosmrs::{cosmwasm, rpc, AccountId, Any, Tx}; +use cosmrs::tx::{self, Msg}; +use cosmrs::{cosmwasm, AccountId, Any, Tx}; use log::debug; use serde::Serialize; use sha2::Digest; use sha2::Sha256; use std::convert::TryInto; use std::time::{Duration, SystemTime}; +use tendermint_rpc::endpoint::broadcast; -const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4); -const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); +#[cfg(feature = "http-client")] +use crate::signing::tx_signer::TxSigner; + +#[cfg(feature = "http-client")] +use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; + +#[cfg(feature = "http-client")] +use cosmrs::rpc::{HttpClient, HttpClientUrl}; + +pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4); +pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); fn empty_fee() -> tx::Fee { tx::Fee { @@ -123,7 +131,10 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .check_response()?; let logs = parse_raw_logs(tx_res.tx_result.log)?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; // TODO: should those strings be extracted into some constants? // the reason I think unwrap here is fine is that if the transaction succeeded and those @@ -184,8 +195,10 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .check_response()?; let logs = parse_raw_logs(tx_res.tx_result.log)?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; // TODO: should those strings be extracted into some constants? // the reason I think unwrap here is fine is that if the transaction succeeded and those // fields do not exist or address is malformed, there's no way we can recover, we're probably connected @@ -212,7 +225,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { fee: Fee, memo: impl Into + Send + 'static, ) -> Result { - let change_admin_msg = cosmwasm::MsgUpdateAdmin { + let change_admin_msg = sealed::cosmwasm::MsgUpdateAdmin { sender: sender_address.clone(), new_admin: new_admin.clone(), contract: contract_address.clone(), @@ -225,8 +238,10 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; Ok(ChangeAdminResult { logs: parse_raw_logs(tx_res.tx_result.log)?, transaction_hash: tx_res.hash, @@ -241,7 +256,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { fee: Fee, memo: impl Into + Send + 'static, ) -> Result { - let change_admin_msg = cosmwasm::MsgClearAdmin { + let change_admin_msg = sealed::cosmwasm::MsgClearAdmin { sender: sender_address.clone(), contract: contract_address.clone(), } @@ -253,8 +268,10 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; Ok(ChangeAdminResult { logs: parse_raw_logs(tx_res.tx_result.log)?, transaction_hash: tx_res.hash, @@ -288,8 +305,10 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; Ok(MigrateResult { logs: parse_raw_logs(tx_res.tx_result.log)?, transaction_hash: tx_res.hash, @@ -323,11 +342,13 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; Ok(ExecuteResult { logs: parse_raw_logs(tx_res.tx_result.log)?, - data: tx_res.tx_result.data, + data: tx_res.tx_result.data.into(), transaction_hash: tx_res.hash, gas_info, }) @@ -364,11 +385,13 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .await? .check_response()?; - let gas_info = GasInfo::new(tx_res.tx_result.gas_wanted, tx_res.tx_result.gas_used); - + let gas_info = GasInfo { + gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(), + gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(), + }; Ok(ExecuteResult { logs: parse_raw_logs(tx_res.tx_result.log)?, - data: tx_res.tx_result.data, + data: tx_res.tx_result.data.into(), transaction_hash: tx_res.hash, gas_info, }) @@ -602,7 +625,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .to_bytes() .map_err(|_| NyxdError::SerializationError("Tx".to_owned()))?; - CosmWasmClient::broadcast_tx_async(self, tx_bytes.into()).await + CosmWasmClient::broadcast_tx_async(self, tx_bytes).await } /// Broadcast a transaction, returning the response from `CheckTx`. @@ -622,7 +645,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .to_bytes() .map_err(|_| NyxdError::SerializationError("Tx".to_owned()))?; - CosmWasmClient::broadcast_tx_sync(self, tx_bytes.into()).await + CosmWasmClient::broadcast_tx_sync(self, tx_bytes).await } /// Broadcast a transaction, returning the response from `DeliverTx`. @@ -643,7 +666,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .to_bytes() .map_err(|_| NyxdError::SerializationError("Tx".to_owned()))?; - CosmWasmClient::broadcast_tx_commit(self, tx_bytes.into()).await + CosmWasmClient::broadcast_tx_commit(self, tx_bytes).await } /// Broadcast a transaction to the network and monitors its inclusion in a block. @@ -664,7 +687,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .to_bytes() .map_err(|_| NyxdError::SerializationError("Tx".to_owned()))?; - self.broadcast_tx(tx_bytes.into()).await + self.broadcast_tx(tx_bytes).await } async fn sign( @@ -709,6 +732,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { ) -> Result; } +#[cfg(feature = "http-client")] #[derive(Debug)] pub struct Client { // TODO: somehow nicely hide this guy if we decide to use our client in offline mode, @@ -722,6 +746,7 @@ pub struct Client { broadcast_timeout: Duration, } +#[cfg(feature = "http-client")] impl Client { pub fn connect_with_signer( endpoint: U, @@ -770,12 +795,13 @@ impl Client { } } +#[cfg(feature = "http-client")] #[async_trait] -impl rpc::Client for Client +impl tendermint_rpc::client::Client for Client where S: Send + Sync, { - async fn perform(&self, request: R) -> Result + async fn perform(&self, request: R) -> Result where R: SimpleRequest, { @@ -783,6 +809,7 @@ where } } +#[cfg(feature = "http-client")] #[async_trait] impl CosmWasmClient for Client where @@ -797,6 +824,7 @@ where } } +#[cfg(feature = "http-client")] #[async_trait] impl SigningCosmWasmClient for Client where @@ -820,7 +848,7 @@ where fee: tx::Fee, memo: impl Into + Send + 'static, signer_data: SignerData, - ) -> Result { + ) -> Result { Ok(self .tx_signer .sign_amino(signer_address, messages, fee, memo, signer_data)?) @@ -833,9 +861,173 @@ where fee: tx::Fee, memo: impl Into + Send + 'static, signer_data: SignerData, - ) -> Result { + ) -> Result { Ok(self .tx_signer .sign_direct(signer_address, messages, fee, memo, signer_data)?) } } + +// a temporary bypass until https://github.com/cosmos/cosmos-rust/pull/419 is merged +mod sealed { + pub mod cosmwasm { + use cosmrs::{proto, tx::Msg, AccountId, ErrorReport, Result}; + + /// MsgUpdateAdmin sets a new admin for a smart contract + #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] + pub struct MsgUpdateAdmin { + /// Sender is the that actor that signed the messages + pub sender: AccountId, + + /// NewAdmin address to be set + pub new_admin: AccountId, + + /// Contract is the address of the smart contract + pub contract: AccountId, + } + + impl Msg for MsgUpdateAdmin { + type Proto = proto::cosmwasm::wasm::v1::MsgUpdateAdmin; + } + + impl TryFrom for MsgUpdateAdmin { + type Error = ErrorReport; + + fn try_from( + proto: proto::cosmwasm::wasm::v1::MsgUpdateAdmin, + ) -> Result { + MsgUpdateAdmin::try_from(&proto) + } + } + + impl TryFrom<&proto::cosmwasm::wasm::v1::MsgUpdateAdmin> for MsgUpdateAdmin { + type Error = ErrorReport; + + fn try_from( + proto: &proto::cosmwasm::wasm::v1::MsgUpdateAdmin, + ) -> Result { + Ok(MsgUpdateAdmin { + sender: proto.sender.parse()?, + new_admin: proto.new_admin.parse()?, + contract: proto.contract.parse()?, + }) + } + } + + impl From for proto::cosmwasm::wasm::v1::MsgUpdateAdmin { + fn from(msg: MsgUpdateAdmin) -> proto::cosmwasm::wasm::v1::MsgUpdateAdmin { + proto::cosmwasm::wasm::v1::MsgUpdateAdmin::from(&msg) + } + } + + impl From<&MsgUpdateAdmin> for proto::cosmwasm::wasm::v1::MsgUpdateAdmin { + fn from(msg: &MsgUpdateAdmin) -> proto::cosmwasm::wasm::v1::MsgUpdateAdmin { + proto::cosmwasm::wasm::v1::MsgUpdateAdmin { + sender: msg.sender.to_string(), + new_admin: msg.new_admin.to_string(), + contract: msg.contract.to_string(), + } + } + } + + /// MsgUpdateAdminResponse returns empty data + #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] + pub struct MsgUpdateAdminResponse {} + + impl Msg for MsgUpdateAdminResponse { + type Proto = proto::cosmwasm::wasm::v1::MsgUpdateAdminResponse; + } + + impl TryFrom for MsgUpdateAdminResponse { + type Error = ErrorReport; + + fn try_from( + _proto: proto::cosmwasm::wasm::v1::MsgUpdateAdminResponse, + ) -> Result { + Ok(MsgUpdateAdminResponse {}) + } + } + + impl From for proto::cosmwasm::wasm::v1::MsgUpdateAdminResponse { + fn from( + _msg: MsgUpdateAdminResponse, + ) -> proto::cosmwasm::wasm::v1::MsgUpdateAdminResponse { + proto::cosmwasm::wasm::v1::MsgUpdateAdminResponse {} + } + } + + /// MsgClearAdmin removes any admin stored for a smart contract + #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] + pub struct MsgClearAdmin { + /// Sender is the that actor that signed the messages + pub sender: AccountId, + + /// Contract is the address of the smart contract + pub contract: AccountId, + } + + impl Msg for MsgClearAdmin { + type Proto = proto::cosmwasm::wasm::v1::MsgClearAdmin; + } + + impl TryFrom for MsgClearAdmin { + type Error = ErrorReport; + + fn try_from(proto: proto::cosmwasm::wasm::v1::MsgClearAdmin) -> Result { + MsgClearAdmin::try_from(&proto) + } + } + + impl TryFrom<&proto::cosmwasm::wasm::v1::MsgClearAdmin> for MsgClearAdmin { + type Error = ErrorReport; + + fn try_from(proto: &proto::cosmwasm::wasm::v1::MsgClearAdmin) -> Result { + Ok(MsgClearAdmin { + sender: proto.sender.parse()?, + contract: proto.contract.parse()?, + }) + } + } + + impl From for proto::cosmwasm::wasm::v1::MsgClearAdmin { + fn from(msg: MsgClearAdmin) -> proto::cosmwasm::wasm::v1::MsgClearAdmin { + proto::cosmwasm::wasm::v1::MsgClearAdmin::from(&msg) + } + } + + impl From<&MsgClearAdmin> for proto::cosmwasm::wasm::v1::MsgClearAdmin { + fn from(msg: &MsgClearAdmin) -> proto::cosmwasm::wasm::v1::MsgClearAdmin { + proto::cosmwasm::wasm::v1::MsgClearAdmin { + sender: msg.sender.to_string(), + contract: msg.contract.to_string(), + } + } + } + + /// MsgClearAdminResponse returns empty data + #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)] + pub struct MsgClearAdminResponse {} + + impl Msg for MsgClearAdminResponse { + type Proto = proto::cosmwasm::wasm::v1::MsgClearAdminResponse; + } + + impl TryFrom for MsgClearAdminResponse { + type Error = ErrorReport; + + fn try_from( + _proto: proto::cosmwasm::wasm::v1::MsgClearAdminResponse, + ) -> Result { + Ok(MsgClearAdminResponse {}) + } + } + + impl From for proto::cosmwasm::wasm::v1::MsgClearAdminResponse { + fn from( + _msg: MsgClearAdminResponse, + ) -> proto::cosmwasm::wasm::v1::MsgClearAdminResponse { + proto::cosmwasm::wasm::v1::MsgClearAdminResponse {} + } + } + } +} diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs index dda27cd8ba..757c8ed201 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs @@ -3,36 +3,35 @@ // TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/ -use crate::nyxd::cosmwasm_client::helpers::parse_proto_coin_vec; use crate::nyxd::cosmwasm_client::logs::Log; use crate::nyxd::error::NyxdError; -use cosmrs::crypto::PublicKey; +use cosmrs::auth::{BaseAccount, ModuleAccount}; +use cosmrs::cosmwasm::{CodeInfoResponse, ContractInfo}; use cosmrs::proto::cosmos::auth::v1beta1::{ BaseAccount as ProtoBaseAccount, ModuleAccount as ProtoModuleAccount, }; -use cosmrs::proto::cosmos::base::abci::v1beta1::{ - GasInfo as ProtoGasInfo, Result as ProtoAbciResult, -}; +use cosmrs::proto::cosmos::base::abci::v1beta1::Result as ProtoAbciResult; use cosmrs::proto::cosmos::tx::v1beta1::SimulateResponse as ProtoSimulateResponse; use cosmrs::proto::cosmos::vesting::v1beta1::{ BaseVestingAccount as ProtoBaseVestingAccount, ContinuousVestingAccount as ProtoContinuousVestingAccount, - DelayedVestingAccount as ProtoDelayedVestingAccount, Period as ProtoPeriod, + DelayedVestingAccount as ProtoDelayedVestingAccount, PeriodicVestingAccount as ProtoPeriodicVestingAccount, PermanentLockedAccount as ProtoPermanentLockedAccount, }; -use cosmrs::proto::cosmwasm::wasm::v1::{ - CodeInfoResponse, ContractCodeHistoryEntry as ProtoContractCodeHistoryEntry, - ContractCodeHistoryOperationType, ContractInfo as ProtoContractInfo, +use cosmrs::tendermint::{abci, Hash}; +use cosmrs::tx::{AccountNumber, SequenceNumber}; +use cosmrs::vesting::{ + BaseVestingAccount, ContinuousVestingAccount, DelayedVestingAccount, PeriodicVestingAccount, + PermanentLockedAccount, }; -use cosmrs::tendermint::abci; -use cosmrs::tendermint::abci::Data; -use cosmrs::tx::{AccountNumber, Gas, SequenceNumber}; -use cosmrs::{tx, AccountId, Any, Coin as CosmosCoin}; +use cosmrs::{AccountId, Any, Coin as CosmosCoin}; use prost::Message; use serde::Serialize; use std::convert::{TryFrom, TryInto}; +pub use cosmrs::abci::GasInfo; + pub type ContractCodeId = u64; #[derive(Serialize)] @@ -44,215 +43,6 @@ pub struct SequenceResponse { pub sequence: SequenceNumber, } -/// BaseAccount defines a base account type. It contains all the necessary fields -/// for basic account functionality. Any custom account type should extend this -/// type for additional functionality (e.g. vesting). -#[derive(Debug)] -pub struct BaseAccount { - /// Bech32 account address - pub address: AccountId, - pub pubkey: Option, - pub account_number: AccountNumber, - pub sequence: SequenceNumber, -} - -impl TryFrom for BaseAccount { - type Error = NyxdError; - - fn try_from(value: ProtoBaseAccount) -> Result { - let address: AccountId = value - .address - .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(value.address.clone()))?; - - let pubkey = value - .pub_key - .map(PublicKey::try_from) - .transpose() - .map_err(|_| NyxdError::InvalidPublicKey(address.clone()))?; - - Ok(BaseAccount { - address, - pubkey, - account_number: value.account_number, - sequence: value.sequence, - }) - } -} - -/// ModuleAccount defines an account for modules that holds coins on a pool. -#[derive(Debug)] -pub struct ModuleAccount { - pub base_account: Option, - pub name: String, - pub permissions: Vec, -} - -impl TryFrom for ModuleAccount { - type Error = NyxdError; - - fn try_from(value: ProtoModuleAccount) -> Result { - let base_account = value.base_account.map(TryFrom::try_from).transpose()?; - - Ok(ModuleAccount { - base_account, - name: value.name, - permissions: value.permissions, - }) - } -} - -/// BaseVestingAccount implements the VestingAccount interface. It contains all -/// the necessary fields needed for any vesting account implementation. -#[derive(Debug)] -pub struct BaseVestingAccount { - pub base_account: Option, - pub original_vesting: Vec, - pub delegated_free: Vec, - pub delegated_vesting: Vec, - pub end_time: i64, -} - -impl TryFrom for BaseVestingAccount { - type Error = NyxdError; - - fn try_from(value: ProtoBaseVestingAccount) -> Result { - let base_account = value.base_account.map(TryFrom::try_from).transpose()?; - - let original_vesting = parse_proto_coin_vec(value.original_vesting)?; - let delegated_free = parse_proto_coin_vec(value.delegated_free)?; - let delegated_vesting = parse_proto_coin_vec(value.delegated_vesting)?; - - Ok(BaseVestingAccount { - base_account, - original_vesting, - delegated_free, - delegated_vesting, - end_time: value.end_time, - }) - } -} - -/// ContinuousVestingAccount implements the VestingAccount interface. It -/// continuously vests by unlocking coins linearly with respect to time. -#[derive(Debug)] -pub struct ContinuousVestingAccount { - pub base_vesting_account: Option, - pub start_time: i64, -} - -impl TryFrom for ContinuousVestingAccount { - type Error = NyxdError; - - fn try_from(value: ProtoContinuousVestingAccount) -> Result { - let base_vesting_account = value - .base_vesting_account - .map(TryFrom::try_from) - .transpose()?; - - Ok(ContinuousVestingAccount { - base_vesting_account, - start_time: value.start_time, - }) - } -} - -/// DelayedVestingAccount implements the VestingAccount interface. It vests all -/// coins after a specific time, but non prior. In other words, it keeps them -/// locked until a specified time. -#[derive(Debug)] -pub struct DelayedVestingAccount { - pub base_vesting_account: Option, -} - -impl TryFrom for DelayedVestingAccount { - type Error = NyxdError; - - fn try_from(value: ProtoDelayedVestingAccount) -> Result { - let base_vesting_account = value - .base_vesting_account - .map(TryFrom::try_from) - .transpose()?; - - Ok(DelayedVestingAccount { - base_vesting_account, - }) - } -} - -/// Period defines a length of time and amount of coins that will vest. -#[derive(Debug)] -pub struct Period { - pub length: i64, - pub amount: Vec, -} - -impl TryFrom for Period { - type Error = NyxdError; - - fn try_from(value: ProtoPeriod) -> Result { - Ok(Period { - length: value.length, - amount: parse_proto_coin_vec(value.amount)?, - }) - } -} - -/// PeriodicVestingAccount implements the VestingAccount interface. It -/// periodically vests by unlocking coins during each specified period. -#[derive(Debug)] -pub struct PeriodicVestingAccount { - pub base_vesting_account: Option, - pub start_time: i64, - pub vesting_periods: Vec, -} - -impl TryFrom for PeriodicVestingAccount { - type Error = NyxdError; - - fn try_from(value: ProtoPeriodicVestingAccount) -> Result { - let base_vesting_account = value - .base_vesting_account - .map(TryFrom::try_from) - .transpose()?; - - let vesting_periods = value - .vesting_periods - .into_iter() - .map(TryFrom::try_from) - .collect::>()?; - - Ok(PeriodicVestingAccount { - base_vesting_account, - start_time: value.start_time, - vesting_periods, - }) - } -} - -/// PermanentLockedAccount implements the VestingAccount interface. It does -/// not ever release coins, locking them indefinitely. Coins in this account can -/// still be used for delegating and for governance votes even while locked. -#[derive(Debug)] -pub struct PermanentLockedAccount { - pub base_vesting_account: Option, -} - -impl TryFrom for PermanentLockedAccount { - type Error = NyxdError; - - fn try_from(value: ProtoPermanentLockedAccount) -> Result { - let base_vesting_account = value - .base_vesting_account - .map(TryFrom::try_from) - .transpose()?; - - Ok(PermanentLockedAccount { - base_vesting_account, - }) - } -} - #[derive(Debug)] pub enum Account { Base(BaseAccount), @@ -335,183 +125,32 @@ impl TryFrom for Account { } } -#[derive(Debug)] -pub struct Code { - pub code_id: ContractCodeId, - - /// Bech32 account address - pub creator: AccountId, - - /// sha256 hash of the code stored - pub data_hash: Vec, -} - -impl TryFrom for Code { - type Error = NyxdError; - - fn try_from(value: CodeInfoResponse) -> Result { - let CodeInfoResponse { - code_id, - creator, - data_hash, - } = value; - - let creator = creator - .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(creator))?; - - Ok(Code { - code_id, - creator, - data_hash, - }) - } -} - #[derive(Debug)] pub struct CodeDetails { - pub code_info: Code, + pub code_info: CodeInfoResponse, /// The original wasm bytes pub data: Vec, } impl CodeDetails { - pub fn new(code_info: Code, data: Vec) -> Self { + pub fn new(code_info: CodeInfoResponse, data: Vec) -> Self { CodeDetails { code_info, data } } } -#[derive(Debug)] -pub(crate) struct ContractInfo { - code_id: ContractCodeId, - creator: AccountId, - admin: Option, - label: String, -} - -impl TryFrom for ContractInfo { - type Error = NyxdError; - - fn try_from(value: ProtoContractInfo) -> Result { - let ProtoContractInfo { - code_id, - creator, - admin, - label, - .. - } = value; - - let admin = if admin.is_empty() { - None - } else { - Some( - admin - .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(admin))?, - ) - }; - - Ok(ContractInfo { - code_id, - creator: creator - .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(creator))?, - admin, - label, - }) - } -} - #[derive(Debug)] pub struct Contract { pub address: AccountId, - pub code_id: ContractCodeId, - - /// Bech32 account address - pub creator: AccountId, - - /// Bech32-encoded admin address - pub admin: Option, - - pub label: String, + pub contract_info: ContractInfo, } impl Contract { pub(crate) fn new(address: AccountId, contract_info: ContractInfo) -> Self { Contract { address, - code_id: contract_info.code_id, - creator: contract_info.creator, - admin: contract_info.admin, - label: contract_info.label, - } - } -} - -#[derive(Clone, Copy, Debug)] -pub enum ContractCodeHistoryEntryOperation { - Init, - Genesis, - Migrate, -} - -#[derive(Debug)] -pub struct ContractCodeHistoryEntry { - /// The source of this history entry - pub operation: ContractCodeHistoryEntryOperation, - pub code_id: ContractCodeId, - pub msg_json: String, -} - -impl TryFrom for ContractCodeHistoryEntry { - type Error = NyxdError; - - fn try_from(value: ProtoContractCodeHistoryEntry) -> Result { - let operation = match ContractCodeHistoryOperationType::from_i32(value.operation) - .ok_or(NyxdError::InvalidContractHistoryOperation)? - { - ContractCodeHistoryOperationType::Unspecified => { - return Err(NyxdError::InvalidContractHistoryOperation) - } - ContractCodeHistoryOperationType::Init => ContractCodeHistoryEntryOperation::Init, - ContractCodeHistoryOperationType::Genesis => ContractCodeHistoryEntryOperation::Genesis, - ContractCodeHistoryOperationType::Migrate => ContractCodeHistoryEntryOperation::Migrate, - }; - - Ok(ContractCodeHistoryEntry { - operation, - code_id: value.code_id, - msg_json: String::from_utf8(value.msg) - .map_err(|_| NyxdError::DeserializationError("Contract history msg".to_owned()))?, - }) - } -} - -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Serialize)] -pub struct GasInfo { - /// GasWanted is the maximum units of work we allow this tx to perform. - pub gas_wanted: Gas, - - /// GasUsed is the amount of gas actually consumed. - pub gas_used: Gas, -} - -impl From for GasInfo { - fn from(value: ProtoGasInfo) -> Self { - GasInfo { - gas_wanted: value.gas_wanted.into(), - gas_used: value.gas_used.into(), - } - } -} - -impl GasInfo { - pub fn new(gas_wanted: Gas, gas_used: Gas) -> Self { - GasInfo { - gas_wanted, - gas_used, + contract_info, } } } @@ -535,31 +174,15 @@ impl TryFrom for AbciResult { type Error = NyxdError; fn try_from(value: ProtoAbciResult) -> Result { - let mut events = Vec::with_capacity(value.events.len()); - - for proto_event in value.events.into_iter() { - let type_str = proto_event.r#type; - - let mut attributes = Vec::with_capacity(proto_event.attributes.len()); - for proto_attribute in proto_event.attributes.into_iter() { - let stringified_ked = String::from_utf8(proto_attribute.key) - .map_err(|_| NyxdError::DeserializationError("EventAttributeKey".to_owned()))?; - let stringified_value = String::from_utf8(proto_attribute.value) - .map_err(|_| NyxdError::DeserializationError("EventAttributeKey".to_owned()))?; - - attributes.push(abci::tag::Tag { - key: stringified_ked.parse().unwrap(), - value: stringified_value.parse().unwrap(), - }) - } - - events.push(abci::Event { - type_str, - attributes, - }) - } + let events = value + .events + .into_iter() + .map(TryInto::try_into) + .collect::, _>>()?; + #[allow(deprecated)] Ok(AbciResult { + // TODO: make sure this actually works since technically we're converting from 0.37 protobuf definition as opposed to 0.34... data: value.data, log: value.log, events, @@ -578,7 +201,10 @@ impl TryFrom for SimulateResponse { fn try_from(value: ProtoSimulateResponse) -> Result { Ok(SimulateResponse { - gas_info: value.gas_info.map(|gas_info| gas_info.into()), + gas_info: value + .gas_info + .map(|gas_info| gas_info.try_into()) + .transpose()?, result: value.result.map(|result| result.try_into()).transpose()?, }) } @@ -608,7 +234,7 @@ pub struct UploadResult { pub logs: Vec, /// Transaction hash (might be used as transaction ID) - pub transaction_hash: tx::Hash, + pub transaction_hash: Hash, pub gas_info: GasInfo, } @@ -645,7 +271,7 @@ pub struct InstantiateResult { pub logs: Vec, /// Transaction hash (might be used as transaction ID) - pub transaction_hash: tx::Hash, + pub transaction_hash: Hash, pub gas_info: GasInfo, } @@ -655,7 +281,7 @@ pub struct ChangeAdminResult { pub logs: Vec, /// Transaction hash (might be used as transaction ID) - pub transaction_hash: tx::Hash, + pub transaction_hash: Hash, pub gas_info: GasInfo, } @@ -665,7 +291,7 @@ pub struct MigrateResult { pub logs: Vec, /// Transaction hash (might be used as transaction ID) - pub transaction_hash: tx::Hash, + pub transaction_hash: Hash, pub gas_info: GasInfo, } @@ -674,10 +300,10 @@ pub struct MigrateResult { pub struct ExecuteResult { pub logs: Vec, - pub data: Data, + pub data: Vec, /// Transaction hash (might be used as transaction ID) - pub transaction_hash: tx::Hash, + pub transaction_hash: Hash, pub gas_info: GasInfo, } diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index b778a56188..b63be6e75c 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -2,34 +2,39 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::cosmwasm_client::types::ContractCodeId; +use cosmrs::tendermint::Hash; use cosmrs::{ - rpc::endpoint::abci_query::AbciQuery, - tendermint::{ - abci::{self, Code as AbciCode}, - block, - }, - tx, AccountId, + tendermint::{abci::Code as AbciCode, block}, + AccountId, }; +use std::{io, time::Duration}; +use tendermint_rpc::endpoint::abci_query::AbciQuery; use thiserror::Error; +#[cfg(feature = "signing")] use crate::signing::direct_wallet::DirectSecp256k1HdWalletError; -pub use cosmrs::rpc::{ + +pub use cosmrs::tendermint::error::Error as TendermintError; +pub use tendermint_rpc::{ error::{Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail}, response_error::{Code, ResponseError}, }; -use std::{io, time::Duration}; #[derive(Debug, Error)] pub enum NyxdError { #[error("No contract address is available to perform the call: {0}")] NoContractAddressAvailable(String), + #[cfg(feature = "signing")] #[error(transparent)] WalletError(#[from] DirectSecp256k1HdWalletError), - #[error("There was an issue on the cosmrs side - {0}")] + #[error("There was an issue on the cosmrs side: {0}")] CosmrsError(#[from] cosmrs::Error), + #[error("There was an issue on the cosmrs side: {0}")] + CosmrsErrorReport(#[from] cosmrs::ErrorReport), + #[error("Failed to derive account address")] AccountDerivationError, @@ -43,7 +48,10 @@ pub enum NyxdError { InvalidTxHash(String), #[error("Tendermint RPC request failed - {0}")] - TendermintError(#[from] TendermintRpcError), + TendermintErrorRpc(#[from] TendermintRpcError), + + #[error("tendermint library failure: {0}")] + TendermintError(#[from] TendermintError), #[error("Failed when attempting to serialize data ({0})")] SerializationError(String), @@ -91,7 +99,7 @@ pub enum NyxdError { "Error when broadcasting tx {hash} at height {height:?}. Error occurred during CheckTx phase. Code: {code}; Raw log: {raw_log}" )] BroadcastTxErrorCheckTx { - hash: tx::Hash, + hash: Hash, height: Option, code: u32, raw_log: String, @@ -101,7 +109,7 @@ pub enum NyxdError { "Error when broadcasting tx {hash} at height {height:?}. Error occurred during DeliverTx phase. Code: {code}; Raw log: {raw_log}" )] BroadcastTxErrorDeliverTx { - hash: tx::Hash, + hash: Hash, height: Option, code: u32, raw_log: String, @@ -116,7 +124,7 @@ pub enum NyxdError { #[error("Abci query failed with code {code} - {log}")] AbciError { code: u32, - log: abci::Log, + log: String, pretty_log: Option, }, @@ -130,7 +138,7 @@ pub enum NyxdError { NoBaseAccountInformationAvailable, #[error("Transaction with ID {hash} has been submitted but not yet found on the chain. You might want to check for it later. There was a total wait of {} seconds", .timeout.as_secs())] - BroadcastTimeout { hash: tx::Hash, timeout: Duration }, + BroadcastTimeout { hash: Hash, timeout: Duration }, #[error("Cosmwasm std error: {0}")] CosmwasmStdError(#[from] cosmwasm_std::StdError), @@ -148,7 +156,7 @@ pub fn parse_abci_query_result(query_result: AbciQuery) -> Result Ok(query_result), AbciCode::Err(code) => Err(NyxdError::AbciError { - code, + code: code.into(), log: query_result.log.clone(), pretty_log: try_parse_abci_log(&query_result.log), }), @@ -157,11 +165,8 @@ pub fn parse_abci_query_result(query_result: AbciQuery) -> Result Option { - if log - .value() - .contains("Maximum amount of locked coins has already been pledged") - { +fn try_parse_abci_log(log: &str) -> Option { + if log.contains("Maximum amount of locked coins has already been pledged") { Some("Maximum amount of locked tokens has already been used. You can only use up to 10% of your locked tokens for bonding and delegating.".to_string()) } else { None @@ -171,7 +176,7 @@ fn try_parse_abci_log(log: &abci::Log) -> Option { impl NyxdError { pub fn is_tendermint_response_timeout(&self) -> bool { match &self { - NyxdError::TendermintError(TendermintRpcError( + NyxdError::TendermintErrorRpc(TendermintRpcError( TendermintRpcErrorDetail::Response(err), _, )) => { @@ -198,7 +203,7 @@ impl NyxdError { pub fn is_tendermint_response_duplicate(&self) -> bool { match &self { - NyxdError::TendermintError(TendermintRpcError( + NyxdError::TendermintErrorRpc(TendermintRpcError( TendermintRpcErrorDetail::Response(err), _, )) => { diff --git a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs index 10ae3a7bb7..caccceb436 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::error::NyxdError; -use cosmrs::tx::Gas; use cosmrs::Coin; +use cosmrs::Gas; use cosmwasm_std::{Decimal, Fraction, Uint128}; use nym_config::defaults; use std::ops::Mul; @@ -25,7 +25,7 @@ impl<'a> Mul for &'a GasPrice { type Output = Coin; fn mul(self, gas_limit: Gas) -> Self::Output { - let limit_uint128 = Uint128::from(gas_limit.value()); + let limit_uint128 = Uint128::from(gas_limit); let mut amount = self.amount * limit_uint128; let gas_price_numerator = self.amount.numerator(); @@ -122,7 +122,7 @@ mod tests { fn gas_limit_multiplication() { // real world example that caused an issue when the result was rounded down let gas_price: GasPrice = "0.025upunk".parse().unwrap(); - let gas_limit: Gas = 157500u64.into(); + let gas_limit: Gas = 157500u64; let fee = &gas_price * gas_limit; // the failing behaviour was result value of 3937 diff --git a/common/client-libs/validator-client/src/nyxd/fee/mod.rs b/common/client-libs/validator-client/src/nyxd/fee/mod.rs index 6b857f8a66..0d67544203 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/mod.rs @@ -116,8 +116,8 @@ impl GasAdjustable for Gas { if adjustment == 1.0 { *self } else { - let adjusted = (self.value() as f32 * adjustment).ceil(); - (adjusted as u64).into() + let adjusted = (*self as f32 * adjustment).ceil(); + adjusted as u64 } } } @@ -125,9 +125,9 @@ impl GasAdjustable for Gas { // a workaround to provide serde implementation for tx::Fee. We don't want to ever expose any of those // types to the public and ideally they will get replaced by proper implementation inside comrs mod sealed { - use cosmrs::tx::{self, Gas}; - use cosmrs::Coin as CosmosCoin; + use cosmrs::tx::{self}; use cosmrs::{AccountId, Denom as CosmosDenom}; + use cosmrs::{Coin as CosmosCoin, Gas}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[derive(Serialize, Deserialize, Clone)] diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 0d90eb2387..404124df8d 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -1,51 +1,67 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::cosmwasm_client::signing_client; -use crate::nyxd::cosmwasm_client::types::{ - Account, ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, - InstantiateResult, MigrateResult, SequenceResponse, SimulateResponse, UploadResult, -}; +use crate::nyxd::cosmwasm_client::types::Account; use crate::nyxd::error::NyxdError; -use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; -use crate::signing::signer::OfflineSigner; -use cosmrs::cosmwasm; -use cosmrs::rpc::endpoint::block::Response as BlockResponse; -use cosmrs::rpc::query::Query; -use cosmrs::rpc::Error as TendermintRpcError; -use cosmrs::rpc::HttpClientUrl; -use cosmrs::tx::Msg; use log::{debug, trace}; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; -use std::time::SystemTime; +use tendermint_rpc::{endpoint::block::Response as BlockResponse, query::Query}; + +#[cfg(feature = "http-client")] +use tendermint_rpc::Error as TendermintRpcError; pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient; -pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; pub use crate::nyxd::fee::Fee; pub use coin::Coin; pub use cosmrs::bank::MsgSend; -pub use cosmrs::rpc::endpoint::tx::Response as TxResponse; -pub use cosmrs::rpc::endpoint::validators::Response as ValidatorResponse; -pub use cosmrs::rpc::HttpClient as QueryNyxdClient; -pub use cosmrs::rpc::Paging; -pub use cosmrs::tendermint::abci::responses::{DeliverTx, Event}; -pub use cosmrs::tendermint::abci::tag::Tag; +pub use cosmrs::tendermint::abci::{response::DeliverTx, Event, EventAttribute}; pub use cosmrs::tendermint::block::Height; -pub use cosmrs::tendermint::hash; +pub use cosmrs::tendermint::hash::{self, Algorithm, Hash}; pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo; pub use cosmrs::tendermint::Time as TendermintTime; -pub use cosmrs::tx::{self, Gas}; +pub use cosmrs::tx::{self}; pub use cosmrs::Coin as CosmosCoin; +pub use cosmrs::Gas; pub use cosmrs::{bip32, AccountId, Denom}; -use cosmwasm_std::Addr; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; -pub use signing_client::Client as SigningNyxdClient; -pub use traits::{VestingQueryClient, VestingSigningClient}; +pub use tendermint_rpc::{client::Client as TendermintClient, Request, Response, SimpleRequest}; +pub use tendermint_rpc::{ + endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse}, + Paging, +}; +#[cfg(feature = "http-client")] +pub use cosmrs::rpc::{HttpClient as QueryNyxdClient, HttpClientUrl}; + +#[cfg(all(feature = "signing", feature = "http-client"))] +use crate::nyxd::cosmwasm_client::signing_client; +#[cfg(feature = "signing")] +use crate::nyxd::cosmwasm_client::types::{ + ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, + MigrateResult, SequenceResponse, SimulateResponse, UploadResult, +}; +#[cfg(all(feature = "signing", feature = "http-client"))] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; +#[cfg(all(feature = "signing", feature = "http-client"))] +use crate::signing::signer::OfflineSigner; +#[cfg(feature = "signing")] +use cosmrs::cosmwasm; +#[cfg(feature = "signing")] +use cosmrs::tx::Msg; +#[cfg(feature = "signing")] +use cosmwasm_std::Addr; +#[cfg(feature = "signing")] +use std::time::SystemTime; + +#[cfg(feature = "signing")] +pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; + +#[cfg(all(feature = "signing", feature = "http-client"))] +pub use signing_client::Client as SigningNyxdClient; + +#[cfg(all(feature = "signing", feature = "http-client"))] pub type DirectSigningNyxdClient = SigningNyxdClient; pub mod coin; @@ -152,10 +168,13 @@ impl Config { pub struct NyxdClient { client: C, config: Config, + // TODO: refactor because that field is only really used for signing + #[allow(dead_code)] client_address: Option>, simulated_gas_multiplier: f32, } +#[cfg(feature = "http-client")] impl NyxdClient { pub fn connect(config: Config, endpoint: U) -> Result, NyxdError> where @@ -165,11 +184,12 @@ impl NyxdClient { client: QueryNyxdClient::new(endpoint)?, config, client_address: None, - simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, + simulated_gas_multiplier: crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } } +#[cfg(all(feature = "signing", feature = "http-client"))] impl NyxdClient> { // TODO: rename this one pub fn connect_with_mnemonic( @@ -187,12 +207,14 @@ impl NyxdClient> { } } +#[cfg(all(feature = "signing", feature = "http-client"))] impl NyxdClient> where S: OfflineSigner, // I have no idea why S::Error: Into bound wouldn't do the trick NyxdError: From, { + #[cfg(feature = "http-client")] pub fn connect_with_signer( config: Config, endpoint: U, @@ -214,10 +236,11 @@ where client: SigningNyxdClient::connect_with_signer(endpoint, signer, gas_price)?, config, client_address: Some(client_address), - simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, + simulated_gas_multiplier: crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } + #[cfg(feature = "http-client")] pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> where U: TryInto, @@ -230,133 +253,47 @@ where } } -impl NyxdClient { - pub fn current_config(&self) -> &Config { - &self.config - } - - pub fn current_chain_details(&self) -> &ChainDetails { - &self.config.chain_details - } - - pub fn set_mixnet_contract_address(&mut self, address: AccountId) { - self.config.mixnet_contract_address = Some(address); - } - - pub fn set_vesting_contract_address(&mut self, address: AccountId) { - self.config.vesting_contract_address = Some(address); - } - - pub fn set_bandwidth_claim_contract_address(&mut self, address: AccountId) { - self.config.bandwidth_claim_contract_address = Some(address); - } - - pub fn set_coconut_bandwidth_contract_address(&mut self, address: AccountId) { - self.config.coconut_bandwidth_contract_address = Some(address); - } - - pub fn set_multisig_contract_address(&mut self, address: AccountId) { - self.config.multisig_contract_address = Some(address); - } - - pub fn set_service_provider_contract_address(&mut self, address: AccountId) { - self.config.service_provider_contract_address = Some(address); - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn mixnet_contract_address(&self) -> &AccountId { - self.config.mixnet_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn vesting_contract_address(&self) -> &AccountId { - self.config.vesting_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn bandwidth_claim_contract_address(&self) -> &AccountId { - self.config - .bandwidth_claim_contract_address - .as_ref() - .unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn coconut_bandwidth_contract_address(&self) -> &AccountId { - self.config - .coconut_bandwidth_contract_address - .as_ref() - .unwrap() - } - - pub fn group_contract_address(&self) -> &AccountId { - self.config.group_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn multisig_contract_address(&self) -> &AccountId { - self.config.multisig_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn coconut_dkg_contract_address(&self) -> &AccountId { - self.config.coconut_dkg_contract_address.as_ref().unwrap() - } - - // The service provider directory contract is optional, so we return an Option not a Result - pub fn service_provider_contract_address(&self) -> Option<&AccountId> { - self.config.service_provider_contract_address.as_ref() - } - - // The name service contract is optional, so we return an Option not a Result - pub fn name_service_contract_address(&self) -> Option<&AccountId> { - self.config.name_service_contract_address.as_ref() - } - - pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { - self.simulated_gas_multiplier = multiplier; - } - - pub async fn query_contract_smart( - &self, - contract: &AccountId, - query_msg: &M, - ) -> Result +#[cfg(feature = "signing")] +impl NyxdClient +where + C: SigningCosmWasmClient + Sync, +{ + pub fn address(&self) -> &AccountId where - C: CosmWasmClient + Sync, - M: ?Sized + Serialize + Sync, - for<'a> T: Deserialize<'a>, + C: SigningCosmWasmClient, { - self.client.query_contract_smart(contract, query_msg).await + // if this is a signing client (as required by the trait bound), it must have the address set + &self.client_address.as_ref().unwrap()[0] } - pub async fn query_contract_raw( - &self, - contract: &AccountId, - query_data: Vec, - ) -> Result, NyxdError> + pub fn cw_address(&self) -> Addr where - C: CosmWasmClient + Sync, + C: SigningCosmWasmClient, { - self.client.query_contract_raw(contract, query_data).await + // the call to unchecked is fine here as we're converting directly from `AccountId` + // which must have been a valid bech32 address + Addr::unchecked(self.address().as_ref()) + } + + pub async fn account_sequence(&self) -> Result + where + C: SigningCosmWasmClient + Sync, + { + self.client.get_sequence(self.address()).await + } + + pub fn signer(&self) -> &::Signer + where + C: SigningCosmWasmClient, + { + self.client.signer() + } + + pub fn gas_price(&self) -> &GasPrice + where + C: SigningCosmWasmClient, + { + self.client.gas_price() } pub fn wrap_contract_execute_message( @@ -377,175 +314,6 @@ impl NyxdClient { }) } - pub fn address(&self) -> &AccountId - where - C: SigningCosmWasmClient, - { - // if this is a signing client (as required by the trait bound), it must have the address set - &self.client_address.as_ref().unwrap()[0] - } - - pub fn cw_address(&self) -> Addr - where - C: SigningCosmWasmClient, - { - // the call to unchecked is fine here as we're converting directly from `AccountId` - // which must have been a valid bech32 address - Addr::unchecked(self.address().as_ref()) - } - - pub fn signer(&self) -> &::Signer - where - C: SigningCosmWasmClient, - { - self.client.signer() - } - - pub fn gas_price(&self) -> &GasPrice - where - C: SigningCosmWasmClient, - { - self.client.gas_price() - } - - pub fn gas_adjustment(&self) -> GasAdjustment { - self.simulated_gas_multiplier - } - - // ============= - // CHAIN RELATED - // ============= - - // CHAIN QUERIES - - pub async fn account_sequence(&self) -> Result - where - C: SigningCosmWasmClient + Sync, - { - self.client.get_sequence(self.address()).await - } - - pub async fn get_account_details( - &self, - address: &AccountId, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_account(address).await - } - - pub async fn get_account_public_key( - &self, - address: &AccountId, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - if let Some(account) = self.client.get_account(address).await? { - let base_account = account.try_get_base_account()?; - return Ok(base_account.pubkey); - } - - Ok(None) - } - - pub async fn get_current_block_timestamp(&self) -> Result - where - C: CosmWasmClient + Sync, - { - self.get_block_timestamp(None).await - } - - pub async fn get_block_timestamp( - &self, - height: Option, - ) -> Result - where - C: CosmWasmClient + Sync, - { - Ok(self.client.get_block(height).await?.block.header.time) - } - - pub async fn get_block(&self, height: Option) -> Result - where - C: CosmWasmClient + Sync, - { - self.client.get_block(height).await - } - - pub async fn get_current_block_height(&self) -> Result - where - C: CosmWasmClient + Sync, - { - self.client.get_height().await - } - - /// Obtains the hash of a block specified by the provided height. - /// - /// # Arguments - /// - /// * `height`: height of the block for which we want to obtain the hash. - pub async fn get_block_hash(&self, height: u32) -> Result - where - C: CosmWasmClient + Sync, - { - self.client - .get_block(Some(height)) - .await - .map(|block| block.block_id.hash) - } - - pub async fn get_validators( - &self, - height: u64, - paging: Paging, - ) -> Result - where - C: CosmWasmClient + Sync, - { - Ok(self.client.validators(height as u32, paging).await?) - } - - pub async fn get_balance( - &self, - address: &AccountId, - denom: String, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_balance(address, denom).await - } - - pub async fn get_all_balances(&self, address: &AccountId) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_all_balances(address).await - } - - pub async fn get_tx(&self, id: tx::Hash) -> Result - where - C: CosmWasmClient + Sync, - { - self.client.get_tx(id).await - } - - pub async fn search_tx(&self, query: Query) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.search_tx(query).await - } - - pub async fn get_total_supply(&self) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_total_supply().await - } - pub async fn simulate(&self, messages: I) -> Result where C: SigningCosmWasmClient + Sync, @@ -762,3 +530,264 @@ impl NyxdClient { .await } } + +impl NyxdClient { + pub fn current_config(&self) -> &Config { + &self.config + } + + pub fn current_chain_details(&self) -> &ChainDetails { + &self.config.chain_details + } + + pub fn set_mixnet_contract_address(&mut self, address: AccountId) { + self.config.mixnet_contract_address = Some(address); + } + + pub fn set_vesting_contract_address(&mut self, address: AccountId) { + self.config.vesting_contract_address = Some(address); + } + + pub fn set_bandwidth_claim_contract_address(&mut self, address: AccountId) { + self.config.bandwidth_claim_contract_address = Some(address); + } + + pub fn set_coconut_bandwidth_contract_address(&mut self, address: AccountId) { + self.config.coconut_bandwidth_contract_address = Some(address); + } + + pub fn set_multisig_contract_address(&mut self, address: AccountId) { + self.config.multisig_contract_address = Some(address); + } + + pub fn set_service_provider_contract_address(&mut self, address: AccountId) { + self.config.service_provider_contract_address = Some(address); + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn mixnet_contract_address(&self) -> &AccountId { + self.config.mixnet_contract_address.as_ref().unwrap() + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn vesting_contract_address(&self) -> &AccountId { + self.config.vesting_contract_address.as_ref().unwrap() + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn bandwidth_claim_contract_address(&self) -> &AccountId { + self.config + .bandwidth_claim_contract_address + .as_ref() + .unwrap() + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn coconut_bandwidth_contract_address(&self) -> &AccountId { + self.config + .coconut_bandwidth_contract_address + .as_ref() + .unwrap() + } + + pub fn group_contract_address(&self) -> &AccountId { + self.config.group_contract_address.as_ref().unwrap() + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn multisig_contract_address(&self) -> &AccountId { + self.config.multisig_contract_address.as_ref().unwrap() + } + + // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits + // note: what unwrap is doing here is just moving a failure that would have normally + // occurred in `connect` when attempting to parse an empty address, + // so it's not introducing new source of failure (just moves it) + pub fn coconut_dkg_contract_address(&self) -> &AccountId { + self.config.coconut_dkg_contract_address.as_ref().unwrap() + } + + // The service provider directory contract is optional, so we return an Option not a Result + pub fn service_provider_contract_address(&self) -> Option<&AccountId> { + self.config.service_provider_contract_address.as_ref() + } + + // The name service contract is optional, so we return an Option not a Result + pub fn name_service_contract_address(&self) -> Option<&AccountId> { + self.config.name_service_contract_address.as_ref() + } + + pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { + self.simulated_gas_multiplier = multiplier; + } + + pub async fn query_contract_smart( + &self, + contract: &AccountId, + query_msg: &M, + ) -> Result + where + C: CosmWasmClient + Sync, + M: ?Sized + Serialize + Sync, + for<'a> T: Deserialize<'a>, + { + self.client.query_contract_smart(contract, query_msg).await + } + + pub async fn query_contract_raw( + &self, + contract: &AccountId, + query_data: Vec, + ) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.query_contract_raw(contract, query_data).await + } + + pub fn gas_adjustment(&self) -> GasAdjustment { + self.simulated_gas_multiplier + } + + // ============= + // CHAIN RELATED + // ============= + + // CHAIN QUERIES + + pub async fn get_account_details( + &self, + address: &AccountId, + ) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.get_account(address).await + } + + pub async fn get_account_public_key( + &self, + address: &AccountId, + ) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + if let Some(account) = self.client.get_account(address).await? { + let base_account = account.try_get_base_account()?; + return Ok(base_account.pubkey); + } + + Ok(None) + } + + pub async fn get_current_block_timestamp(&self) -> Result + where + C: CosmWasmClient + Sync, + { + self.get_block_timestamp(None).await + } + + pub async fn get_block_timestamp( + &self, + height: Option, + ) -> Result + where + C: CosmWasmClient + Sync, + { + Ok(self.client.get_block(height).await?.block.header.time) + } + + pub async fn get_block(&self, height: Option) -> Result + where + C: CosmWasmClient + Sync, + { + self.client.get_block(height).await + } + + pub async fn get_current_block_height(&self) -> Result + where + C: CosmWasmClient + Sync, + { + self.client.get_height().await + } + + /// Obtains the hash of a block specified by the provided height. + /// + /// # Arguments + /// + /// * `height`: height of the block for which we want to obtain the hash. + pub async fn get_block_hash(&self, height: u32) -> Result + where + C: CosmWasmClient + Sync, + { + self.client + .get_block(Some(height)) + .await + .map(|block| block.block_id.hash) + } + + pub async fn get_validators( + &self, + height: u64, + paging: Paging, + ) -> Result + where + C: CosmWasmClient + Sync, + { + Ok(self.client.validators(height as u32, paging).await?) + } + + pub async fn get_balance( + &self, + address: &AccountId, + denom: String, + ) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.get_balance(address, denom).await + } + + pub async fn get_all_balances(&self, address: &AccountId) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.get_all_balances(address).await + } + + pub async fn get_tx(&self, id: Hash) -> Result + where + C: CosmWasmClient + Sync, + { + self.client.get_tx(id).await + } + + pub async fn search_tx(&self, query: Query) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.search_tx(query).await + } + + pub async fn get_total_supply(&self) -> Result, NyxdError> + where + C: CosmWasmClient + Sync, + { + self.client.get_total_supply().await + } +} diff --git a/common/client-libs/validator-client/src/nyxd/traits/mod.rs b/common/client-libs/validator-client/src/nyxd/traits/mod.rs index 55fc8c9215..9f6dac5354 100644 --- a/common/client-libs/validator-client/src/nyxd/traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/traits/mod.rs @@ -8,19 +8,24 @@ mod dkg_query_client; mod group_query_client; mod mixnet_query_client; mod multisig_query_client; +mod name_service_query_client; +mod sp_directory_query_client; mod vesting_query_client; +#[cfg(feature = "signing")] mod coconut_bandwidth_signing_client; +#[cfg(feature = "signing")] mod dkg_signing_client; +#[cfg(feature = "signing")] mod mixnet_signing_client; +#[cfg(feature = "signing")] mod multisig_signing_client; -mod vesting_signing_client; - -mod sp_directory_query_client; -mod sp_directory_signing_client; - -mod name_service_query_client; +#[cfg(feature = "signing")] mod name_service_signing_client; +#[cfg(feature = "signing")] +mod sp_directory_signing_client; +#[cfg(feature = "signing")] +mod vesting_signing_client; pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient; pub use dkg_query_client::DkgQueryClient; @@ -31,10 +36,17 @@ pub use name_service_query_client::NameServiceQueryClient; pub use sp_directory_query_client::SpDirectoryQueryClient; pub use vesting_query_client::VestingQueryClient; +#[cfg(feature = "signing")] pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; +#[cfg(feature = "signing")] pub use dkg_signing_client::DkgSigningClient; +#[cfg(feature = "signing")] pub use mixnet_signing_client::MixnetSigningClient; +#[cfg(feature = "signing")] pub use multisig_signing_client::MultisigSigningClient; +#[cfg(feature = "signing")] pub use name_service_signing_client::NameServiceSigningClient; +#[cfg(feature = "signing")] pub use sp_directory_signing_client::SpDirectorySigningClient; +#[cfg(feature = "signing")] pub use vesting_signing_client::VestingSigningClient; diff --git a/common/client-libs/validator-client/src/signing/mod.rs b/common/client-libs/validator-client/src/signing/mod.rs index f2301db26e..d9fa0c30e4 100644 --- a/common/client-libs/validator-client/src/signing/mod.rs +++ b/common/client-libs/validator-client/src/signing/mod.rs @@ -63,7 +63,6 @@ impl SignerData { } } - #[cfg(feature = "nyxd-client")] pub fn new_from_sequence_response( response: crate::nyxd::cosmwasm_client::types::SequenceResponse, chain_id: chain::Id, diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index d57e1c47ac..28f319b875 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -28,7 +28,7 @@ tap = "1" cosmrs = { workspace = true } cosmwasm-std = { workspace = true } -nym-validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../client-libs/validator-client", features = ["signing", "http-client"] } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } nym-network-defaults = { path = "../network-defaults" } diff --git a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs index 87ecdfb3f8..ec10a60193 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs @@ -6,7 +6,7 @@ use log::info; use nym_mixnet_contract_common::{Coin, MixId}; use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs index cd1521dea6..4f8dac045e 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs @@ -5,7 +5,7 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::MixId; use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs index 6d3c480296..e734ddc97d 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs @@ -6,7 +6,7 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::GatewayConfigUpdate; use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs index d6625a878b..21f771c0b3 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs @@ -7,7 +7,7 @@ use log::{info, warn}; use nym_contracts_common::signing::MessageSignature; use nym_mixnet_contract_common::{Coin, Gateway}; use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs index 6a3dc6d2da..f5ff9e3419 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs index e585fe2ec3..8b888e8bd6 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs @@ -8,7 +8,7 @@ use nym_contracts_common::signing::MessageSignature; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::families::FamilyHead; use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs index 0dc0b840d1..9305c56918 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs @@ -6,7 +6,7 @@ use clap::Parser; use log::info; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs index 1ffb2c46b6..5cb06e7762 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs @@ -7,7 +7,7 @@ use log::info; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::families::FamilyHead; use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs index e4af971aa3..5b956b929f 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs @@ -6,7 +6,7 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::MixNodeConfigUpdate; use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs index dd172c8d51..9928dec18f 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs @@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{MixNode, Percent}; use nym_network_defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; -use nym_validator_client::nyxd::{CosmWasmCoin, VestingSigningClient}; +use nym_validator_client::nyxd::{traits::VestingSigningClient, CosmWasmCoin}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs index 131e210646..d38d7f61dc 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs index b0839f97de..0774fd89d6 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs @@ -4,7 +4,7 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs index be2d99a35c..49f717a5af 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::VestingSigningClient; +use nym_validator_client::nyxd::traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/signature/helpers.rs b/common/commands/src/validator/signature/helpers.rs index 1c2d05c9e1..d612c0f994 100644 --- a/common/commands/src/validator/signature/helpers.rs +++ b/common/commands/src/validator/signature/helpers.rs @@ -10,7 +10,7 @@ pub fn secp256k1_verify_with_public_key( public_key_as_bytes: &[u8], signature_as_hex: String, message: String, -) -> Result<(), k256::ecdsa::signature::Error> { +) -> Result<(), k256::ecdsa::Error> { let verifying_key = VerifyingKey::from_sec1_bytes(public_key_as_bytes)?; let signature = Signature::from_str(&signature_as_hex)?; let message_as_bytes = message.into_bytes(); diff --git a/common/commands/src/validator/transactions/get_transaction.rs b/common/commands/src/validator/transactions/get_transaction.rs index 3d1b53e7b2..6ad1bbbd2f 100644 --- a/common/commands/src/validator/transactions/get_transaction.rs +++ b/common/commands/src/validator/transactions/get_transaction.rs @@ -6,7 +6,7 @@ use std::str::FromStr; use crate::context::QueryClient; use crate::utils::show_error; -use cosmrs::tx::Hash; +use cosmrs::tendermint::Hash; use serde_json::json; #[derive(Debug, Parser)] diff --git a/common/commands/src/validator/vesting/balance.rs b/common/commands/src/validator/vesting/balance.rs index 3d5c340027..d5f5af20fe 100644 --- a/common/commands/src/validator/vesting/balance.rs +++ b/common/commands/src/validator/vesting/balance.rs @@ -5,7 +5,7 @@ use clap::Parser; use cosmrs::AccountId; use log::{error, info}; -use nym_validator_client::nyxd::{Coin, VestingQueryClient}; +use nym_validator_client::nyxd::{traits::VestingQueryClient, Coin}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/create_vesting_schedule.rs b/common/commands/src/validator/vesting/create_vesting_schedule.rs index e861cc227e..524cdf67e1 100644 --- a/common/commands/src/validator/vesting/create_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/create_vesting_schedule.rs @@ -8,8 +8,8 @@ use log::info; use nym_mixnet_contract_common::Coin; use nym_network_defaults::NymNetworkDetails; +use nym_validator_client::nyxd::traits::VestingSigningClient; use nym_validator_client::nyxd::AccountId; -use nym_validator_client::nyxd::VestingSigningClient; use nym_validator_client::nyxd::{CosmosCoin, Denom}; use nym_vesting_contract_common::messages::VestingSpecification; use nym_vesting_contract_common::PledgeCap; diff --git a/common/commands/src/validator/vesting/query_vesting_schedule.rs b/common/commands/src/validator/vesting/query_vesting_schedule.rs index 397d4b9075..9c8facfb70 100644 --- a/common/commands/src/validator/vesting/query_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/query_vesting_schedule.rs @@ -6,7 +6,7 @@ use cosmrs::AccountId; use cosmwasm_std::Coin as CosmWasmCoin; use log::{error, info}; -use nym_validator_client::nyxd::{Coin, VestingQueryClient}; +use nym_validator_client::nyxd::{traits::VestingQueryClient, Coin}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/withdraw_vested.rs b/common/commands/src/validator/vesting/withdraw_vested.rs index d98a958cf1..a85e960a1a 100644 --- a/common/commands/src/validator/vesting/withdraw_vested.rs +++ b/common/commands/src/validator/vesting/withdraw_vested.rs @@ -4,7 +4,10 @@ use clap::Parser; use log::info; -use nym_validator_client::nyxd::{Coin, VestingQueryClient, VestingSigningClient}; +use nym_validator_client::nyxd::{ + traits::{VestingQueryClient, VestingSigningClient}, + Coin, +}; use crate::context::SigningClient; use crate::utils::show_error; diff --git a/common/credentials/src/coconut/bandwidth.rs b/common/credentials/src/coconut/bandwidth.rs index 9c87e75341..7e458456df 100644 --- a/common/credentials/src/coconut/bandwidth.rs +++ b/common/credentials/src/coconut/bandwidth.rs @@ -6,14 +6,14 @@ // right now this has no double-spending protection, spender binding, etc // it's the simplest possible case +use cosmrs::tendermint::hash::Algorithm; +use cosmrs::tendermint::Hash; use nym_coconut_interface::{ hash_to_scalar, prepare_blind_sign, Attribute, BlindSignRequest, Credential, Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey, }; use nym_crypto::asymmetric::{encryption, identity}; -use cosmrs::tx::Hash; - use super::utils::prepare_credential_for_spending; use crate::error::Error; @@ -129,7 +129,9 @@ impl BandwidthVoucher { let binding_number = Option::::from(PrivateAttribute::from_bytes(&buff)) .ok_or_else(scalar_err)?; buff.copy_from_slice(&bytes[2 * 32..3 * 32]); - let tx_hash = Hash::new(buff); + let tx_hash = Hash::from_bytes(Algorithm::Sha256, &buff).map_err(|_| { + Error::BandwidthVoucherDeserializationError(String::from("Invalid transaction Hash")) + })?; buff.copy_from_slice(&bytes[3 * 32..4 * 32]); let signing_key = identity::PrivateKey::from_bytes(&buff).map_err(|_| { Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) @@ -282,6 +284,7 @@ pub fn prepare_for_spending( #[cfg(test)] mod test { use super::*; + use cosmrs::tendermint::hash::Algorithm; use nym_coconut_interface::Base58; use rand::rngs::OsRng; @@ -292,7 +295,7 @@ mod test { ¶ms, "1234".to_string(), "voucher info".to_string(), - Hash::new([0; 32]), + Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), identity::PrivateKey::from_base58_string( identity::KeyPair::new(&mut rng) .private_key() diff --git a/common/ledger/Cargo.toml b/common/ledger/Cargo.toml index dda242bf14..5ea9badd52 100644 --- a/common/ledger/Cargo.toml +++ b/common/ledger/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bip32 = "0.4.0" +bip32 = "0.5.1" k256 = { workspace = true } ledger-transport = "0.10.0" ledger-transport-hid = "0.10.0" diff --git a/common/ledger/src/addr_secp256k1.rs b/common/ledger/src/addr_secp256k1.rs index 682161be9d..d6c5957481 100644 --- a/common/ledger/src/addr_secp256k1.rs +++ b/common/ledger/src/addr_secp256k1.rs @@ -27,7 +27,7 @@ impl TryFrom>> for AddrSecp256k1Response { } let (pub_key, addr) = bytes.split_at(33); - let public_key = k256::PublicKey::from_bytes( + let public_key = PublicKey::from_bytes( PublicKeyBytes::try_from(pub_key).expect("Public key should be 33 bytes"), )?; let address = String::from_utf8(addr.to_vec()).unwrap(); diff --git a/common/mixnode-common/Cargo.toml b/common/mixnode-common/Cargo.toml index 9a3f0ce851..62fec9422a 100644 --- a/common/mixnode-common/Cargo.toml +++ b/common/mixnode-common/Cargo.toml @@ -36,9 +36,7 @@ nym-sphinx-framing = { path = "../nymsphinx/framing" } nym-sphinx-params = { path = "../nymsphinx/params" } nym-sphinx-types = { path = "../nymsphinx/types" } nym-task = { path = "../task" } -nym-validator-client = { path = "../client-libs/validator-client", features = [ - "nyxd-client", -] } +nym-validator-client = { path = "../client-libs/validator-client" } nym-bin-common = { path = "../bin-common" } cfg-if = "1.0.0" diff --git a/common/socks5-client-core/Cargo.toml b/common/socks5-client-core/Cargo.toml index 1057955242..9ca792f8b1 100644 --- a/common/socks5-client-core/Cargo.toml +++ b/common/socks5-client-core/Cargo.toml @@ -26,7 +26,7 @@ nym-service-providers-common = { path = "../../service-providers/common" } nym-socks5-requests = { path = "../socks5/requests" } nym-sphinx = { path = "../nymsphinx" } nym-task = { path = "../task" } -nym-validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../client-libs/validator-client" } [features] default = [] diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index 0dd4879310..c99bbf3e30 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -22,9 +22,7 @@ ts-rs = "6.1.2" cosmwasm-std = { workspace = true } cosmrs = { workspace = true } -nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "nyxd-client", -] } +nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } diff --git a/common/types/src/gas.rs b/common/types/src/gas.rs index cf63a32d60..9c389cc863 100644 --- a/common/types/src/gas.rs +++ b/common/types/src/gas.rs @@ -1,4 +1,4 @@ -use cosmrs::tx::Gas as CosmrsGas; +use cosmrs::Gas as CosmrsGas; use nym_validator_client::nyxd::cosmwasm_client::types::GasInfo as ValidatorClientGasInfo; use serde::{Deserialize, Serialize}; @@ -21,8 +21,14 @@ impl Gas { impl From for Gas { fn from(gas: CosmrsGas) -> Self { + Gas { gas_units: gas } + } +} + +impl From for Gas { + fn from(value: i64) -> Self { Gas { - gas_units: gas.value(), + gas_units: value.try_into().unwrap_or_default(), } } } diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index a317ccbe1b..5e1dec9f48 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -34,4 +34,4 @@ nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-co nym-network-defaults = { path = "../common/network-defaults" } nym-bin-common = { path = "../common/bin-common"} nym-task = { path = "../common/task" } -nym-validator-client = { path = "../common/client-libs/validator-client", features=["nyxd-client"] } +nym-validator-client = { path = "../common/client-libs/validator-client", features=["http-client"] } diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 41bd7ecfe3..763b3ab676 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -60,7 +60,7 @@ nym-sphinx = { path = "../common/nymsphinx" } nym-statistics-common = { path = "../common/statistics" } nym-task = { path = "../common/task" } nym-types = { path = "../common/types" } -nym-validator-client = { path = "../common/client-libs/validator-client", features = [ "nyxd-client" ] } +nym-validator-client = { path = "../common/client-libs/validator-client" } [build-dependencies] tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } diff --git a/integrations/bity/Cargo.toml b/integrations/bity/Cargo.toml index 4ae51337c9..db8bdc9420 100644 --- a/integrations/bity/Cargo.toml +++ b/integrations/bity/Cargo.toml @@ -14,9 +14,7 @@ eyre = "0.6.5" cosmrs = { workspace = true } nym-cli-commands = { path = "../../common/commands" } -nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "nyxd-client", -] } +nym-validator-client = { path = "../../common/client-libs/validator-client" } [dev-dependencies] anyhow = "1" diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 4cfec3402a..f9b378f59d 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -92,7 +92,7 @@ nym-task = { path = "../common/task" } nym-topology = { path = "../common/topology" } nym-api-requests = { path = "nym-api-requests" } nym-validator-client = { path = "../common/client-libs/validator-client", features = [ - "nyxd-client", + "http-client", "signing" ] } nym-bin-common = { path = "../common/bin-common" } nym-node-tester-utils = { path = "../common/node-tester-utils" } diff --git a/nym-api/src/coconut/deposit.rs b/nym-api/src/coconut/deposit.rs index 685fee70f3..3d6b8fb2de 100644 --- a/nym-api/src/coconut/deposit.rs +++ b/nym-api/src/coconut/deposit.rs @@ -35,14 +35,14 @@ pub async fn extract_encryption_key( .tx_result .events .iter() - .find(|event| event.type_str == format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE)) + .find(|event| event.kind == format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE)) .ok_or(CoconutError::DepositEventNotFound)? .attributes .as_ref(); - let deposit_value = attributes + let deposit_value: &str = attributes .iter() - .find(|tag| tag.key.as_ref() == DEPOSIT_VALUE) + .find(|tag| tag.key == DEPOSIT_VALUE) .ok_or(CoconutError::DepositValueNotFound)? .value .as_ref(); @@ -54,9 +54,9 @@ pub async fn extract_encryption_key( )); } - let deposit_info = attributes + let deposit_info: &str = attributes .iter() - .find(|tag| tag.key.as_ref() == DEPOSIT_INFO) + .find(|tag| tag.key == DEPOSIT_INFO) .ok_or(CoconutError::DepositInfoNotFound)? .value .as_ref(); @@ -69,21 +69,19 @@ pub async fn extract_encryption_key( } let verification_key = identity::PublicKey::from_base58_string( - attributes + &attributes .iter() - .find(|tag| tag.key.as_ref() == DEPOSIT_IDENTITY_KEY) + .find(|tag| tag.key == DEPOSIT_IDENTITY_KEY) .ok_or(CoconutError::DepositVerifKeyNotFound)? - .value - .as_ref(), + .value, )?; let encryption_key = encryption::PublicKey::from_base58_string( - attributes + &attributes .iter() - .find(|tag| tag.key.as_ref() == DEPOSIT_ENCRYPTION_KEY) + .find(|tag| tag.key == DEPOSIT_ENCRYPTION_KEY) .ok_or(CoconutError::DepositEncrKeyNotFound)? - .value - .as_ref(), + .value, )?; verification_key.verify(&message, &signature)?; @@ -97,8 +95,8 @@ mod test { use crate::coconut::tests::tx_entry_fixture; use nym_coconut::{prepare_blind_sign, BlindSignRequest, Parameters}; use nym_config::defaults::VOUCHER_INFO; - use nym_validator_client::nyxd::tx::Hash; - use nym_validator_client::nyxd::{Event, Tag}; + use nym_validator_client::nyxd::Hash; + use nym_validator_client::nyxd::{Event, EventAttribute}; use rand_07::rngs::OsRng; use std::str::FromStr; @@ -182,7 +180,7 @@ mod test { ); tx_entry.tx_result.events.push(Event { - type_str: format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE), + kind: format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE), attributes: vec![], }); let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -193,9 +191,10 @@ mod test { CoconutError::DepositValueNotFound.to_string(), ); - tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![Tag { + tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "10".parse().unwrap(), + index: false, }]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) .await @@ -206,9 +205,10 @@ mod test { .to_string(), ); - tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![Tag { + tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) .await @@ -219,13 +219,15 @@ mod test { ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: "bandwidth deposit info".parse().unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -241,13 +243,15 @@ mod test { ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -259,17 +263,20 @@ mod test { ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: "verification key".parse().unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -284,19 +291,22 @@ mod test { )); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: "2eSxwquNJb2nZTEW5p4rbqjHfBaz9UaNhjHHiexPN4He" .parse() .unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -308,23 +318,27 @@ mod test { ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: "6EJGMdEq7t8Npz54uPkftGsdmj7DKntLVputAnDfVZB2" .parse() .unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(), value: "encryption key".parse().unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -340,23 +354,27 @@ mod test { let expected_encryption_key = "HxnTpWTkgigSTAysVKLE8pEiUULHdTT1BxFfzfJvQRi6"; tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: "6EJGMdEq7t8Npz54uPkftGsdmj7DKntLVputAnDfVZB2" .parse() .unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(), value: expected_encryption_key.parse().unwrap(), + index: false, }, ]; let err = extract_encryption_key(&correct_request, tx_entry.clone()) @@ -405,25 +423,29 @@ mod test { 4, ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: "64auwDkWan7R8yH1Mwe9dS4qXgrDBCUNDg3Q4KFnd2P5" .parse() .unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(), value: "HxnTpWTkgigSTAysVKLE8pEiUULHdTT1BxFfzfJvQRi6" .parse() .unwrap(), + index: false, }, ]; let encryption_key = extract_encryption_key(&correct_request, tx_entry.clone()) diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index 225d04bc3b..775e761fea 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -11,7 +11,7 @@ pub(crate) fn accepted_vote_err(ret: Result<(), CoconutError>) -> Result<(), Coc let accepted_err = nym_multisig_contract_common::error::ContractError::NotOpen {}.to_string(); // If redundant voting is not the case, error out on all other error variants - if !log.value().contains(&accepted_err) { + if !log.contains(&accepted_err) { ret?; } } diff --git a/nym-api/src/coconut/tests.rs b/nym-api/src/coconut/tests.rs index 0648e9c8ca..37153f1370 100644 --- a/nym-api/src/coconut/tests.rs +++ b/nym-api/src/coconut/tests.rs @@ -28,7 +28,9 @@ use nym_validator_client::nym_api::routes::{ API_VERSION, BANDWIDTH, COCONUT_BLIND_SIGN, COCONUT_ROUTES, COCONUT_VERIFY_BANDWIDTH_CREDENTIAL, }; use nym_validator_client::nyxd::Coin; -use nym_validator_client::nyxd::{tx::Hash, AccountId, DeliverTx, Event, Fee, Tag, TxResponse}; +use nym_validator_client::nyxd::{ + AccountId, Algorithm, DeliverTx, Event, EventAttribute, Fee, Hash, TxResponse, +}; use crate::coconut::State; use crate::support::storage::NymApiStorage; @@ -365,7 +367,7 @@ impl super::client::Client for DummyClient { .add_attribute(NODE_INDEX, assigned_index.to_string())], }], data: Default::default(), - transaction_hash: Hash::new([0; 32]), + transaction_hash: Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), gas_info: Default::default(), }) } @@ -389,7 +391,7 @@ impl super::client::Client for DummyClient { Ok(ExecuteResult { logs: vec![], data: Default::default(), - transaction_hash: Hash::new([0; 32]), + transaction_hash: Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), gas_info: Default::default(), }) } @@ -457,7 +459,7 @@ impl super::client::Client for DummyClient { .add_attribute(DKG_PROPOSAL_ID, proposal_id.to_string())], }], data: Default::default(), - transaction_hash: Hash::new([0; 32]), + transaction_hash: Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), gas_info: Default::default(), }) } @@ -498,7 +500,7 @@ pub fn tx_entry_fixture(tx_hash: &str) -> TxResponse { events: vec![], codespace: Default::default(), }, - tx: vec![].into(), + tx: vec![], proof: None, } } @@ -749,33 +751,37 @@ async fn blind_sign_correct() { let mut tx_entry = tx_entry_fixture(&tx_hash.to_string()); tx_entry.tx_result.events.push(Event { - type_str: format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE), + kind: format!("wasm-{}", DEPOSITED_FUNDS_EVENT_TYPE), attributes: vec![], }); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ - Tag { + EventAttribute { key: DEPOSIT_VALUE.parse().unwrap(), value: "1234".parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_INFO.parse().unwrap(), value: VOUCHER_INFO.parse().unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_IDENTITY_KEY.parse().unwrap(), value: identity_keypair .public_key() .to_base58_string() .parse() .unwrap(), + index: false, }, - Tag { + EventAttribute { key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(), value: encryption_keypair .public_key() .to_base58_string() .parse() .unwrap(), + index: false, }, ]; tx_db diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 8d2fe53dc5..e35098ee1f 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -35,13 +35,13 @@ use nym_validator_client::nyxd::{ cosmwasm_client::types::ExecuteResult, traits::{ CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, GroupQueryClient, - MultisigQueryClient, MultisigSigningClient, NameServiceQueryClient, + MultisigQueryClient, MultisigSigningClient, NameServiceQueryClient, VestingQueryClient, }, Fee, }; use nym_validator_client::nyxd::{ hash::{Hash, SHA256_HASH_SIZE}, - AccountId, Coin, DirectSigningNyxdClient, TendermintTime, VestingQueryClient, + AccountId, Coin, DirectSigningNyxdClient, TendermintTime, }; use nym_validator_client::ValidatorClientError; use nym_vesting_contract_common::AccountVestingCoins; @@ -321,8 +321,8 @@ impl crate::coconut::client::Client for Client { &self, tx_hash: &str, ) -> crate::coconut::error::Result { - let tx_hash = tx_hash - .parse::() + let tx_hash: Hash = tx_hash + .parse() .map_err(|_| CoconutError::TxHashParseError)?; Ok(self.0.read().await.nyxd.get_tx(tx_hash).await?) } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 89bfdbc8f3..5f48b27bd0 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -226,6 +226,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -255,13 +261,13 @@ dependencies = [ [[package]] name = "bip32" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ - "bs58", + "bs58 0.5.0", "hmac 0.12.1", - "k256", + "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -278,8 +284,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", - "rand_core 0.6.4", + "rand 0.7.3", + "rand_core 0.5.1", "serde", "unicode-normalization", "zeroize", @@ -338,7 +344,7 @@ dependencies = [ "cc", "cfg-if", "constant_time_eq", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -419,8 +425,14 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.9.9", + "sha2 0.10.6", ] [[package]] @@ -462,6 +474,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "cairo-rs" @@ -786,9 +801,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" dependencies = [ "prost", "prost-types", @@ -797,18 +812,16 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" +checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa", + "ecdsa 0.16.8", "eyre", "getrandom 0.2.10", - "k256", - "prost", - "prost-types", + "k256 0.13.1", "rand_core 0.6.4", "serde", "serde_json", @@ -824,9 +837,9 @@ version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", - "k256", + "k256 0.11.6", "rand_core 0.6.4", "thiserror", ] @@ -1003,6 +1016,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1111,6 +1136,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cw-controllers" version = "1.0.1" @@ -1285,6 +1323,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1329,11 +1377,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -1451,10 +1500,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.7", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -1463,7 +1526,30 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.1.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -1473,7 +1559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", - "ed25519", + "ed25519 1.5.3", "rand 0.7.3", "serde", "sha2 0.9.9", @@ -1507,16 +1593,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.6", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "pkcs8", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle 2.4.1", "zeroize", ] @@ -1661,6 +1766,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.5" @@ -2000,6 +2115,7 @@ dependencies = [ "serde", "typenum", "version_check", + "zeroize", ] [[package]] @@ -2211,6 +2327,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "gtk" version = "0.15.5" @@ -2455,7 +2582,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -2874,19 +3001,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", - "sha3", ] [[package]] -name = "keccak" -version = "0.1.4" +name = "k256" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ - "cpufeatures", + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", ] [[package]] @@ -3373,7 +3504,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmrs", "cosmwasm-std", "getset", @@ -3464,7 +3595,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "digest 0.9.0", "ff 0.11.1", "getrandom 0.2.10", @@ -3505,7 +3636,7 @@ dependencies = [ name = "nym-coconut-interface" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "getset", "nym-coconut", "serde", @@ -3564,7 +3695,6 @@ dependencies = [ "tauri-codegen", "tauri-macros", "tempfile", - "tendermint-rpc", "thiserror", "time", "tokio", @@ -3578,7 +3708,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "schemars", "serde", @@ -3615,10 +3745,10 @@ version = "0.4.0" dependencies = [ "aes 0.8.2", "blake3", - "bs58", + "bs58 0.4.0", "cipher 0.4.4", "ctr 0.9.2", - "digest 0.10.6", + "digest 0.10.7", "ed25519-dalek", "generic-array 0.14.7", "hkdf 0.12.3", @@ -3638,7 +3768,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381 0.6.0", - "bs58", + "bs58 0.4.0", "ff 0.11.1", "group 0.11.0", "lazy_static", @@ -3688,7 +3818,7 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "futures", "generic-array 0.14.7", "log", @@ -3720,7 +3850,7 @@ dependencies = [ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "humantime-serde", "log", @@ -3951,7 +4081,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -4060,7 +4190,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58", + "bs58 0.4.0", "log", "nym-bin-common", "nym-crypto", @@ -4109,6 +4239,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.9.9", + "tendermint-rpc", "thiserror", "tokio", "url", @@ -4409,11 +4540,12 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -4640,8 +4772,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.7", + "spki 0.7.2", ] [[package]] @@ -4760,9 +4902,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.10.4" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", @@ -4770,9 +4912,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", @@ -4783,11 +4925,10 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes", "prost", ] @@ -5045,11 +5186,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + [[package]] name = "rfd" version = "0.10.0" @@ -5095,18 +5246,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest 0.10.7", ] [[package]] @@ -5318,10 +5458,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.7", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle 2.4.1", "zeroize", ] @@ -5702,7 +5856,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -5726,17 +5880,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.6", - "keccak", + "digest 0.10.7", ] [[package]] @@ -5763,7 +5907,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -5835,7 +5989,7 @@ dependencies = [ "aes 0.7.5", "arrayref", "blake2", - "bs58", + "bs58 0.4.0", "byteorder", "chacha", "curve25519-dalek", @@ -5872,7 +6026,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.7", ] [[package]] @@ -6182,6 +6346,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.109" @@ -6511,28 +6681,28 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" +checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ - "async-trait", "bytes", - "ed25519", - "ed25519-dalek", + "digest 0.10.7", + "ed25519 2.2.1", + "ed25519-consensus", "flex-error", "futures", - "k256", + "k256 0.13.1", "num-traits", "once_cell", "prost", "prost-types", - "ripemd160", + "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.9.9", - "signature", + "sha2 0.10.6", + "signature 2.1.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -6542,9 +6712,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" +checksum = "71a72dbbea6dde12045d261f2c70c0de039125675e8a026c8d5ad34522756372" dependencies = [ "flex-error", "serde", @@ -6556,9 +6726,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" dependencies = [ "bytes", "flex-error", @@ -6574,9 +6744,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" +checksum = "d119d83a130537fc4a98c3c9eb6899ebe857fea4860400a61675bfb5f0b35129" dependencies = [ "async-trait", "bytes", @@ -6589,9 +6759,11 @@ dependencies = [ "hyper-rustls", "peg", "pin-project", + "semver 1.0.17", "serde", "serde_bytes", "serde_json", + "subtle 2.4.1", "subtle-encoding", "tendermint", "tendermint-config", diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index edce6a2bb6..c3c1b0a895 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -37,7 +37,7 @@ serde_json = "1.0" serde_repr = "0.1" tap = "1.0.1" tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private-api", "notification-all", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] } -tendermint-rpc = "0.23.0" +#tendermint-rpc = "0.23.0" thiserror = "1.0" time = { version = "0.3.17", features = ["local-offset"] } tokio = { version = "1.24.1", features = ["sync", "time"] } diff --git a/nym-connect/mobile/src-tauri/Cargo.toml b/nym-connect/mobile/src-tauri/Cargo.toml index 0817f11d62..28ea437cdc 100644 --- a/nym-connect/mobile/src-tauri/Cargo.toml +++ b/nym-connect/mobile/src-tauri/Cargo.toml @@ -43,7 +43,7 @@ serde_repr = "0.1" tap = "1.0.1" # tauri = { git = "https://github.com/tauri-apps/tauri", branch = "next", features = ["clipboard-write-text", "native-tls-vendored", "notification-all", "shell-open"] } tauri = { version = "2.0.0-alpha.3", features = ["clipboard-write-text", "native-tls-vendored", "notification-all", "shell-open"] } -tendermint-rpc = "0.23.0" +#tendermint-rpc = "0.23.0" thiserror = "1.0" time = { version = "0.3.17", features = ["local-offset"] } tokio = { version = "1.24.1", features = ["sync", "time"] } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 14bc9eb0e6..2da872c4fc 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -200,6 +200,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -220,13 +226,13 @@ checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" [[package]] name = "bip32" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ - "bs58", + "bs58 0.5.0", "hmac 0.12.1", - "k256", + "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -292,7 +298,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -306,7 +312,7 @@ dependencies = [ "cc", "cfg-if", "constant_time_eq", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -373,8 +379,14 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.9.9", + "sha2 0.10.6", ] [[package]] @@ -416,6 +428,9 @@ name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +dependencies = [ + "serde", +] [[package]] name = "cairo-rs" @@ -740,9 +755,9 @@ dependencies = [ [[package]] name = "cosmos-sdk-proto" -version = "0.13.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a" +checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" dependencies = [ "prost", "prost-types", @@ -751,18 +766,16 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4" +checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa", + "ecdsa 0.16.8", "eyre", "getrandom 0.2.10", - "k256", - "prost", - "prost-types", + "k256 0.13.1", "rand_core 0.6.4", "serde", "serde_json", @@ -778,9 +791,9 @@ version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", - "k256", + "k256 0.11.6", "rand_core 0.6.4", "thiserror", ] @@ -917,6 +930,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1031,6 +1056,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cw-controllers" version = "1.0.1" @@ -1171,6 +1209,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1215,11 +1263,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -1331,10 +1380,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der 0.7.7", + "digest 0.10.7", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", + "spki 0.7.2", ] [[package]] @@ -1343,7 +1406,30 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.1.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -1353,7 +1439,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", - "ed25519", + "ed25519 1.5.3", "rand 0.7.3", "serde", "sha2 0.9.9", @@ -1387,16 +1473,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest 0.10.6", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", - "pkcs8", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle 2.4.1", "zeroize", ] @@ -1519,6 +1624,16 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "field-offset" version = "0.3.4" @@ -2005,6 +2120,17 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "gtk" version = "0.15.5" @@ -2204,7 +2330,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -2589,19 +2715,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", - "sha3", ] [[package]] -name = "keccak" -version = "0.1.4" +name = "k256" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ - "cpufeatures", + "cfg-if", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", + "once_cell", + "sha2 0.10.6", + "signature 2.1.0", ] [[package]] @@ -2990,7 +3120,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmrs", "cosmwasm-std", "getset", @@ -3020,7 +3150,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58", + "bs58 0.4.0", "digest 0.9.0", "ff 0.11.1", "getrandom 0.2.10", @@ -3061,7 +3191,7 @@ dependencies = [ name = "nym-coconut-interface" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "getset", "nym-coconut", "serde", @@ -3085,7 +3215,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "schemars", "serde", @@ -3096,7 +3226,7 @@ dependencies = [ name = "nym-crypto" version = "0.4.0" dependencies = [ - "bs58", + "bs58 0.4.0", "ed25519-dalek", "nym-pemstore", "nym-sphinx-types", @@ -3113,7 +3243,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58", + "bs58 0.4.0", "ff 0.11.1", "group 0.11.0", "lazy_static", @@ -3143,7 +3273,7 @@ dependencies = [ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "humantime-serde", "log", @@ -3321,6 +3451,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.9.9", + "tendermint-rpc", "thiserror", "tokio", "url", @@ -3393,7 +3524,7 @@ dependencies = [ [[package]] name = "nym_wallet" -version = "1.2.5" +version = "1.2.6" dependencies = [ "async-trait", "base64 0.13.1", @@ -3408,7 +3539,7 @@ dependencies = [ "fern", "futures", "itertools", - "k256", + "k256 0.13.1", "log", "nym-coconut-interface", "nym-config", @@ -3434,7 +3565,6 @@ dependencies = [ "tauri-codegen", "tauri-macros", "tempfile", - "tendermint-rpc", "thiserror", "time", "tokio", @@ -3666,11 +3796,12 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -3897,8 +4028,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.7", + "spki 0.7.2", ] [[package]] @@ -4029,9 +4170,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.10.4" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", @@ -4039,9 +4180,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", @@ -4052,11 +4193,10 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.10.1" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes", "prost", ] @@ -4316,11 +4456,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + [[package]] name = "rfd" version = "0.10.0" @@ -4366,18 +4516,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug 0.3.0", + "digest 0.10.7", ] [[package]] @@ -4526,10 +4665,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.7", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle 2.4.1", "zeroize", ] @@ -4767,7 +4920,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -4791,17 +4944,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.6", - "keccak", + "digest 0.10.7", ] [[package]] @@ -4828,7 +4971,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", "rand_core 0.6.4", ] @@ -4900,7 +5053,7 @@ dependencies = [ "aes 0.7.5", "arrayref", "blake2 0.8.1", - "bs58", + "bs58 0.4.0", "byteorder", "chacha", "curve25519-dalek", @@ -4928,7 +5081,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der 0.7.7", ] [[package]] @@ -5027,6 +5190,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.107" @@ -5343,28 +5512,28 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8" +checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ - "async-trait", "bytes", - "ed25519", - "ed25519-dalek", + "digest 0.10.7", + "ed25519 2.2.1", + "ed25519-consensus", "flex-error", "futures", - "k256", + "k256 0.13.1", "num-traits", "once_cell", "prost", "prost-types", - "ripemd160", + "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.9.9", - "signature", + "sha2 0.10.6", + "signature 2.1.0", "subtle 2.4.1", "subtle-encoding", "tendermint-proto", @@ -5374,9 +5543,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773" +checksum = "71a72dbbea6dde12045d261f2c70c0de039125675e8a026c8d5ad34522756372" dependencies = [ "flex-error", "serde", @@ -5388,9 +5557,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281" +checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" dependencies = [ "bytes", "flex-error", @@ -5406,9 +5575,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.23.8" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d" +checksum = "d119d83a130537fc4a98c3c9eb6899ebe857fea4860400a61675bfb5f0b35129" dependencies = [ "async-trait", "bytes", @@ -5421,9 +5590,11 @@ dependencies = [ "hyper-rustls", "peg", "pin-project", + "semver 1.0.16", "serde", "serde_bytes", "serde_json", + "subtle 2.4.1", "subtle-encoding", "tendermint", "tendermint-config", diff --git a/nym-wallet/nym-wallet-types/Cargo.toml b/nym-wallet/nym-wallet-types/Cargo.toml index 99d0ef784b..63a4aa5daf 100644 --- a/nym-wallet/nym-wallet-types/Cargo.toml +++ b/nym-wallet/nym-wallet-types/Cargo.toml @@ -11,15 +11,13 @@ serde_json = "1.0" strum = { version = "0.23", features = ["derive"] } ts-rs = "6.1.2" -cosmwasm-std = "1.0.0" -cosmrs = "=0.8.0" +cosmwasm-std = "1.2.0" +cosmrs = "=0.14.0" nym-config = { path = "../../common/config" } nym-network-defaults = { path = "../../common/network-defaults" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } -nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "nyxd-client", -] } +nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } # Used for Type conversion, can be extracted but its a lot of work nym-vesting-contract = { path = "../../contracts/vesting" } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 5e6c9c7318..19b5f0e3c9 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -38,21 +38,21 @@ serde_json = "1.0" serde_repr = "0.1" strum = { version = "0.23", features = ["derive"] } tauri = { version = "=1.2.3", features = ["clipboard-all", "shell-open", "updater", "window-maximize", "window-print"] } -tendermint-rpc = "0.23.0" +#tendermint-rpc = "0.23.0" time = { version = "0.3.17", features = ["local-offset"] } thiserror = "1.0" tokio = { version = "1.10", features = ["full"] } toml = "0.5.8" url = "2.2" -k256 = { version = "0.11", features = ["ecdsa", "sha256"] } +k256 = { version = "0.13", features = ["ecdsa", "sha256"] } base64 = "0.13" zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } -cosmwasm-std = "1.0.0" -cosmrs = "=0.8.0" +cosmwasm-std = "1.2.0" +cosmrs = "=0.14.0" nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "nyxd-client", + "signing", "http-client" ] } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" } diff --git a/nym-wallet/src-tauri/src/error.rs b/nym-wallet/src-tauri/src/error.rs index 8cee3018d5..3d9374c22a 100644 --- a/nym-wallet/src-tauri/src/error.rs +++ b/nym-wallet/src-tauri/src/error.rs @@ -1,4 +1,5 @@ use nym_contracts_common::signing::SigningAlgorithm; +use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_types::error::TypesError; use nym_validator_client::nym_api::error::NymAPIError; @@ -25,7 +26,7 @@ pub enum BackendError { #[error("{source}")] TendermintError { #[from] - source: tendermint_rpc::Error, + source: cosmrs::rpc::Error, }, #[error("{pretty_error}")] NyxdError { @@ -149,6 +150,9 @@ pub enum BackendError { #[error(transparent)] Ed25519Recovery(#[from] Ed25519RecoveryError), + #[error("failed to verify ed25519 signature: {0}")] + Ed25519SignatureError(#[from] identity::SignatureError), + #[error("This command ({name}) has been removed. Please try to use {alternative} instead.")] RemovedCommand { name: String, alternative: String }, } diff --git a/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index 87c961b38e..dd7cb4558c 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -103,7 +103,6 @@ fn main() { utils::owns_gateway, utils::owns_mixnode, utils::get_env, - utils::get_old_and_incorrect_hardcoded_fee, utils::try_convert_pubkey_to_mix_id, utils::default_mixnode_cost_params, nym_api::status::compute_mixnode_reward_estimation, diff --git a/nym-wallet/src-tauri/src/operations/simulate/mod.rs b/nym-wallet/src-tauri/src/operations/simulate/mod.rs index b3e032d000..5662f56fda 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/mod.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use cosmrs::tx; -use cosmrs::tx::Gas; +use cosmrs::Gas; use nym_types::fees::FeeDetails; use nym_validator_client::nyxd::cosmwasm_client::types::GasInfo; use nym_validator_client::nyxd::{CosmosCoin, Fee, GasAdjustable, GasAdjustment, GasPrice}; diff --git a/nym-wallet/src-tauri/src/operations/vesting/bond.rs b/nym-wallet/src-tauri/src/operations/vesting/bond.rs index 38583a877b..f2077e5694 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/bond.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/bond.rs @@ -1,19 +1,17 @@ -use std::cmp::Ordering; - use crate::error::BackendError; use crate::nyxd_client; +use crate::operations::helpers::{ + verify_gateway_bonding_sign_payload, verify_mixnode_bonding_sign_payload, +}; use crate::state::WalletState; use crate::{Gateway, MixNode}; use nym_contracts_common::signing::MessageSignature; use nym_mixnet_contract_common::{GatewayConfigUpdate, MixNodeConfigUpdate}; - -use crate::operations::helpers::{ - verify_gateway_bonding_sign_payload, verify_mixnode_bonding_sign_payload, -}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::{Fee, VestingSigningClient}; +use nym_validator_client::nyxd::{traits::VestingSigningClient, Fee}; +use std::cmp::Ordering; #[tauri::command] pub async fn vesting_bond_gateway( diff --git a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs index 2cc873499a..ff7c33710f 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs @@ -6,7 +6,7 @@ use crate::state::WalletState; use nym_mixnet_contract_common::MixId; use nym_types::currency::DecCoin; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::{Fee, VestingSigningClient}; +use nym_validator_client::nyxd::{traits::VestingSigningClient, Fee}; #[tauri::command] pub async fn vesting_delegate_to_mixnode( diff --git a/nym-wallet/src-tauri/src/operations/vesting/queries.rs b/nym-wallet/src-tauri/src/operations/vesting/queries.rs index b8ed343554..a24e26d001 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/queries.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/queries.rs @@ -8,7 +8,7 @@ use cosmwasm_std::Timestamp; use nym_types::currency::DecCoin; use nym_types::vesting::VestingAccountInfo; use nym_types::vesting::{OriginalVestingResponse, PledgeData}; -use nym_validator_client::nyxd::VestingQueryClient; +use nym_validator_client::nyxd::traits::VestingQueryClient; use nym_vesting_contract_common::Period; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/vesting/rewards.rs b/nym-wallet/src-tauri/src/operations/vesting/rewards.rs index 7d64fafed4..dbedb302e3 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/rewards.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/rewards.rs @@ -5,8 +5,8 @@ use crate::error::BackendError; use crate::state::WalletState; use nym_mixnet_contract_common::MixId; use nym_types::transaction::TransactionExecuteResult; +use nym_validator_client::nyxd::traits::VestingSigningClient; use nym_validator_client::nyxd::Fee; -use nym_validator_client::nyxd::VestingSigningClient; #[tauri::command] pub async fn vesting_claim_operator_reward( diff --git a/nym-wallet/src-tauri/src/utils.rs b/nym-wallet/src-tauri/src/utils.rs index 9fe353302c..e5aed4e092 100644 --- a/nym-wallet/src-tauri/src/utils.rs +++ b/nym-wallet/src-tauri/src/utils.rs @@ -9,9 +9,7 @@ use nym_mixnet_contract_common::{IdentityKey, MixId, Percent}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::{tx, Coin, CosmosCoin, Gas, GasPrice}; use nym_wallet_types::app::AppEnv; -use serde::{Deserialize, Serialize}; fn get_env_as_option(key: &str) -> Option { match ::std::env::var(key) { @@ -79,116 +77,3 @@ pub async fn default_mixnode_cost_params( }, }) } - -#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)] -pub enum Operation { - Upload, - Init, - Migrate, - ChangeAdmin, - Send, - - BondMixnode, - BondMixnodeOnBehalf, - UnbondMixnode, - UnbondMixnodeOnBehalf, - UpdateMixnodeConfig, - DelegateToMixnode, - DelegateToMixnodeOnBehalf, - UndelegateFromMixnode, - UndelegateFromMixnodeOnBehalf, - - BondGateway, - BondGatewayOnBehalf, - UnbondGateway, - UnbondGatewayOnBehalf, - - UpdateContractSettings, - - BeginMixnodeRewarding, - FinishMixnodeRewarding, - - TrackUnbondGateway, - TrackUnbondMixnode, - WithdrawVestedCoins, - TrackUndelegation, - CreatePeriodicVestingAccount, - - AdvanceCurrentInterval, - AdvanceCurrentEpoch, - WriteRewardedSet, - ClearRewardedSet, - UpdateMixnetAddress, - CheckpointMixnodes, - ReconcileDelegations, -} - -impl Operation { - fn default_gas_limit(&self) -> Gas { - match self { - Operation::Upload => 3_000_000u64.into(), - Operation::Init => 500_000u64.into(), - Operation::Migrate => 200_000u64.into(), - Operation::ChangeAdmin => 80_000u64.into(), - Operation::Send => 80_000u64.into(), - - Operation::BondMixnode => 175_000u64.into(), - Operation::BondMixnodeOnBehalf => 200_000u64.into(), - Operation::UnbondMixnode => 175_000u64.into(), - Operation::UnbondMixnodeOnBehalf => 175_000u64.into(), - Operation::UpdateMixnodeConfig => 175_000u64.into(), - Operation::DelegateToMixnode => 175_000u64.into(), - Operation::DelegateToMixnodeOnBehalf => 175_000u64.into(), - Operation::UndelegateFromMixnode => 175_000u64.into(), - Operation::UndelegateFromMixnodeOnBehalf => 175_000u64.into(), - - Operation::BondGateway => 175_000u64.into(), - Operation::BondGatewayOnBehalf => 200_000u64.into(), - Operation::UnbondGateway => 175_000u64.into(), - Operation::UnbondGatewayOnBehalf => 200_000u64.into(), - - Operation::UpdateContractSettings => 175_000u64.into(), - Operation::BeginMixnodeRewarding => 175_000u64.into(), - Operation::FinishMixnodeRewarding => 175_000u64.into(), - Operation::TrackUnbondGateway => 175_000u64.into(), - Operation::TrackUnbondMixnode => 175_000u64.into(), - Operation::WithdrawVestedCoins => 175_000u64.into(), - Operation::TrackUndelegation => 175_000u64.into(), - Operation::CreatePeriodicVestingAccount => 175_000u64.into(), - Operation::AdvanceCurrentInterval => 175_000u64.into(), - Operation::WriteRewardedSet => 175_000u64.into(), - Operation::ClearRewardedSet => 175_000u64.into(), - Operation::UpdateMixnetAddress => 80_000u64.into(), - Operation::CheckpointMixnodes => 175_000u64.into(), - Operation::ReconcileDelegations => 500_000u64.into(), - Operation::AdvanceCurrentEpoch => 175_000u64.into(), - } - } - - fn calculate_fee(gas_price: &GasPrice, gas_limit: Gas) -> CosmosCoin { - gas_price * gas_limit - } - - fn determine_custom_fee(gas_price: &GasPrice, gas_limit: Gas) -> tx::Fee { - let fee = Self::calculate_fee(gas_price, gas_limit); - tx::Fee::from_amount_and_gas(fee, gas_limit) - } - - fn default_fee(&self, gas_price: &GasPrice) -> tx::Fee { - Self::determine_custom_fee(gas_price, self.default_gas_limit()) - } -} - -#[tauri::command] -pub async fn get_old_and_incorrect_hardcoded_fee( - state: tauri::State<'_, WalletState>, - operation: Operation, -) -> Result { - let guard = state.read().await; - let mut approximate_fee = operation.default_fee(guard.current_client()?.nyxd.gas_price()); - // on all our chains it should only ever contain a single type of currency - assert_eq!(approximate_fee.amount.len(), 1); - let coin: Coin = approximate_fee.amount.pop().unwrap().into(); - log::info!("hardcoded fee for {:?} is {:?}", operation, coin); - guard.attempt_convert_to_display_dec_coin(coin) -} diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index 94f6656df5..7aaced99aa 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -18,7 +18,7 @@ nym-sphinx = { path = "../../../common/nymsphinx" } nym-task = { path = "../../../common/task" } nym-topology = { path = "../../../common/topology" } nym-socks5-client-core = { path = "../../../common/socks5-client-core" } -nym-validator-client = { path = "../../../common/client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../../../common/client-libs/validator-client", features = ["http-client"] } futures = "0.3" log = { workspace = true } diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index 4dd1d9197f..ea5cad9e65 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -22,5 +22,5 @@ tap = "1" nym-cli-commands = { path = "../../common/commands" } nym-bin-common = { path = "../../common/bin-common"} -nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] } +nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] } nym-network-defaults = { path = "../../common/network-defaults" } diff --git a/tools/ts-rs-cli/Cargo.toml b/tools/ts-rs-cli/Cargo.toml index 366bbe3ef4..41f9ead98d 100644 --- a/tools/ts-rs-cli/Cargo.toml +++ b/tools/ts-rs-cli/Cargo.toml @@ -11,7 +11,7 @@ ts-rs = "6.1.2" walkdir = "2" nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "nyxd-client", "generate-ts" + "generate-ts" ] } nym-api-requests = { path = "../../nym-api/nym-api-requests", features = ["generate-ts"] } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract", features = [ "generate-ts" ]} From 053e047cca23f94417793be5c5355dc7adddef31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=A1=EF=B8=8F2FakTor=E2=9A=A1=EF=B8=8F?= Date: Wed, 28 Jun 2023 13:59:51 +0200 Subject: [PATCH 39/59] Update network-requester-setup.md --- documentation/docs/src/nodes/network-requester-setup.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/documentation/docs/src/nodes/network-requester-setup.md b/documentation/docs/src/nodes/network-requester-setup.md index 6ee560b5b4..6f389a2fce 100644 --- a/documentation/docs/src/nodes/network-requester-setup.md +++ b/documentation/docs/src/nodes/network-requester-setup.md @@ -193,10 +193,10 @@ sudo ufw enable sudo ufw status ``` -Finally open your requester's p2p port, as well as ports for ssh and incoming traffic connections: +Finally open your requester's ssh port to incoming administration connections: ``` -sudo ufw allow 22,9000/tcp +sudo ufw allow 22/tcp # check the status of the firewall sudo ufw status ``` @@ -249,7 +249,3 @@ This command should return the following: ### Requester port reference All network-requester-specific port configuration can be found in `$HOME/.nym/service-providers/network-requester//config/config.toml`. If you do edit any port configs, remember to restart your client and requester processes. - -| Default port | Use | -|--------------|---------------------------| -| 9000 | Listen for Client traffic | From d843407ba71b1e9fc23a849b83dde7ecec659cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9A=A1=EF=B8=8F2FakTor=E2=9A=A1=EF=B8=8F?= Date: Wed, 28 Jun 2023 16:07:32 +0200 Subject: [PATCH 40/59] Update network-requester-setup.md --- documentation/docs/src/nodes/network-requester-setup.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/documentation/docs/src/nodes/network-requester-setup.md b/documentation/docs/src/nodes/network-requester-setup.md index 6f389a2fce..aa7edefd6f 100644 --- a/documentation/docs/src/nodes/network-requester-setup.md +++ b/documentation/docs/src/nodes/network-requester-setup.md @@ -201,8 +201,6 @@ sudo ufw allow 22/tcp sudo ufw status ``` -For more information about your requester's port configuration, check the [requester port reference table](./network-requester-setup.md#requester-port-reference) below. - ## Using your network requester The next thing to do is use your requester, share its address with friends (or whoever you want to help privacy-enhance their app traffic). Is this safe to do? If it was an open proxy, this would be unsafe, because any Nym user could make network requests to any system on the internet. From 5781d3043f1f338d347dc3004e48fdb08ced27fc Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Mon, 10 Jul 2023 09:44:33 +0200 Subject: [PATCH 41/59] removed command information from mix node + gateway guide --- documentation/docs/src/nodes/gateway-setup.md | 2 -- documentation/docs/src/nodes/mix-node-setup.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/documentation/docs/src/nodes/gateway-setup.md b/documentation/docs/src/nodes/gateway-setup.md index fe48fc8566..a933dc5b04 100644 --- a/documentation/docs/src/nodes/gateway-setup.md +++ b/documentation/docs/src/nodes/gateway-setup.md @@ -153,8 +153,6 @@ Follow these steps to upgrade your binary and update its config file: * re-run `init` with the same values as you used initially. **This will just update the config file, it will not overwrite existing keys**. * restart your gateway process with the new binary. -> Do **not** use the `upgrade` command: there is a known error with the command that will be fixed in a subsequent release. - #### Step 2: updating your node information in the smart contract Follow these steps to update the information about your node which is publically avaliable from the [Nym API](https://validator.nymtech.net/api/swagger/index.html) and information displayed on the [mixnet explorer](https://explorer.nymtech.net). diff --git a/documentation/docs/src/nodes/mix-node-setup.md b/documentation/docs/src/nodes/mix-node-setup.md index 408ef20b99..2f93797e1e 100644 --- a/documentation/docs/src/nodes/mix-node-setup.md +++ b/documentation/docs/src/nodes/mix-node-setup.md @@ -191,8 +191,6 @@ Follow these steps to upgrade your mix node binary and update its config file: * re-run `init` with the same values as you used initially. **This will just update the config file, it will not overwrite existing keys**. * restart your mix node process with the new binary. -> Do **not** use the `upgrade` command: there is a known error with the command that will be fixed in a subsequent release. - #### Step 2: updating your node information in the smart contract Follow these steps to update the information about your mix node which is publically avaliable from the [Nym API](https://validator.nymtech.net/api/swagger/index.html) and information displayed on the [mixnet explorer](https://explorer.nymtech.net). From 4306cec49cba456630f0ed364597e07d36ea3472 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Mon, 10 Jul 2023 09:56:22 +0200 Subject: [PATCH 42/59] version bumps --- documentation/dev-portal/book.toml | 6 +++--- documentation/docs/book.toml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 3b81f82751..7060f9078b 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -47,10 +47,10 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install` # variables preprocessor: import variables into files # https://gitlab.com/tglman/mdbook-variables/ [preprocessor.variables.variables] -# code prerequisites versions minimum_rust_version = "1.66" -# TODO remove this in place of develop in next release -platform_release_version = "v1.1.21" +# vars for links: TODO think on how to streamline updating +platform_release_version = "v1.1.24" +wallet_release_version = "v1.2.6" [preprocessor.last-changed] command = "mdbook-last-changed" diff --git a/documentation/docs/book.toml b/documentation/docs/book.toml index b70997a556..2ef42bc719 100644 --- a/documentation/docs/book.toml +++ b/documentation/docs/book.toml @@ -49,8 +49,8 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install` [preprocessor.variables.variables] minimum_rust_version = "1.66" # vars for links: TODO think on how to streamline updating -platform_release_version = "v1.1.22" -wallet_release_version = "v1.2.5" +platform_release_version = "v1.1.24" +wallet_release_version = "v1.2.6" [preprocessor.last-changed] command = "mdbook-last-changed" From 2c2dd54028e469b06df35cc2957afef117f89213 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 12:34:26 +0200 Subject: [PATCH 43/59] updated sdk documentation with surb example --- documentation/docs/src/sdk/rust.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/documentation/docs/src/sdk/rust.md b/documentation/docs/src/sdk/rust.md index 9e60d40efd..68004b7576 100644 --- a/documentation/docs/src/sdk/rust.md +++ b/documentation/docs/src/sdk/rust.md @@ -56,14 +56,19 @@ If you're integrating mixnet functionality into an existing app and want to inte ### Anonymous replies with SURBs Both functions used to send messages through the mixnet (`send_str` and `send_bytes`) send a pre-determined number of SURBs along with their messages by default. -The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L35): +The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L34): ```rust,noplayground -{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:30}} +{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:34}} ``` You can read more about how SURBs function under the hood [here](../architecture/traffic-flow.md#private-replies-using-surbs). +In order to reply to an incoming message using SURBs, you can construct a `recipient` from the `sender_tag` sent along with the message you wish to reply to: + +```rust,noplayground +{{#include ../../../../sdk/rust/nym-sdk/examples/surb-reply.rs}} +``` ### Importing and using a custom network topology If you want to send traffic through a sub-set of nodes (for instance, ones you control, or a small test setup) when developing, debugging, or peforming research, you will need to import these nodes as a custom network topology, instead of grabbing it from the [`Mainnet Nym-API`](https://validator.nymtech.net/api/swagger/index.html) (`examples/custom_topology_provider.rs`). From b79ec60381f74bb37169b6eae2ca25f8120e7c41 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 12:45:30 +0200 Subject: [PATCH 44/59] * added serinko + alexia to book authors * version bumps for next release --- documentation/dev-portal/book.toml | 6 +++--- documentation/docs/book.toml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 7060f9078b..36470b0a94 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -1,6 +1,6 @@ [book] title = "Nym Developer Portal" -authors = ["Max Hampshire"] +authors = ["Max Hampshire, Serinko, Alexia Lorenza Martinel"] language = "en" multilingual = false src = "src" @@ -49,8 +49,8 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install` [preprocessor.variables.variables] minimum_rust_version = "1.66" # vars for links: TODO think on how to streamline updating -platform_release_version = "v1.1.24" -wallet_release_version = "v1.2.6" +platform_release_version = "v1.1.26" +wallet_release_version = "v1.2.7" [preprocessor.last-changed] command = "mdbook-last-changed" diff --git a/documentation/docs/book.toml b/documentation/docs/book.toml index 2ef42bc719..996a7ec4e4 100644 --- a/documentation/docs/book.toml +++ b/documentation/docs/book.toml @@ -1,6 +1,6 @@ [book] title = "Nym Docs" -authors = ["Max Hampshire"] +authors = ["Max Hampshire, Serinko, Alexia Lorenza Martinel"] description = "Nym technical documentation" language = "en" multilingual = false # for the moment - ideally work on chinese, brazillian, spanish next @@ -49,8 +49,8 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install` [preprocessor.variables.variables] minimum_rust_version = "1.66" # vars for links: TODO think on how to streamline updating -platform_release_version = "v1.1.24" -wallet_release_version = "v1.2.6" +platform_release_version = "v1.1.25" +wallet_release_version = "v1.2.7" [preprocessor.last-changed] command = "mdbook-last-changed" From 93cd8821c324f2966b10814759ed7cf4423938b4 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 13:16:11 +0200 Subject: [PATCH 45/59] version update --- documentation/dev-portal/book.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 36470b0a94..cf434a31f5 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -49,7 +49,7 @@ assets_version = "2.0.0" # do not edit: managed by `mdbook-admonish install` [preprocessor.variables.variables] minimum_rust_version = "1.66" # vars for links: TODO think on how to streamline updating -platform_release_version = "v1.1.26" +platform_release_version = "v1.1.25" wallet_release_version = "v1.2.7" [preprocessor.last-changed] From 91341733c1353be6320502dfb1f12355414642eb Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 13:51:55 +0200 Subject: [PATCH 46/59] updated NR guide with list explainer + info on comments in local allow list --- .../docs/src/nodes/network-requester-setup.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/documentation/docs/src/nodes/network-requester-setup.md b/documentation/docs/src/nodes/network-requester-setup.md index aa7edefd6f..ccea6bfc0f 100644 --- a/documentation/docs/src/nodes/network-requester-setup.md +++ b/documentation/docs/src/nodes/network-requester-setup.md @@ -8,7 +8,6 @@ ``` - ## Network Requester Whitelist If you have access to a server, you can run the network requester, which allows Nym users to send outbound requests from their local machine through the mixnet to a server, which then makes the request on their behalf, shielding them (and their metadata) from clearnet, untrusted and unknown infrastructure, such as email or message client servers. @@ -65,6 +64,34 @@ p2pify.com 2001:67c:4e8::/48 2001:b28:f23c::/48 2a0a:f280::/32 + +# nym matrix server +nymtech.chat + +# generic matrix server backends +vector.im +matrix.org + +# monero desktop - mainnet +212.83.175.67 +212.83.172.165 +176.9.0.187 +88.198.163.90 +95.217.25.101 +136.244.105.131 +104.238.221.81 +66.85.74.134 +88.99.173.38 +51.79.173.165 + +# monero desktop - stagenet +162.210.173.150 +176.9.0.187 +88.99.173.38 +51.79.173.165 + +# alephium +alephium.org ``` ## Network Requester Directory @@ -207,9 +234,18 @@ The next thing to do is use your requester, share its address with friends (or w To make things a bit less stressful for administrators, the Network Requester drops all incoming requests by default. In order for it to make requests, you need to add specific domains to the `allowed.list` file at `$HOME/.nym/service-providers/network-requester/allowed.list`. +### Global vs local allow lists +Your Network Requester will check for a domain against 2 lists before allowing traffic through for a particular domain or IP. + +* The first list is the default list on the [nymtech.net server](). Your Requester will not check against this list every time, but instead will keep a record of accepted domains in memory. + +* The second is the local `allowed.list` file. + ### Supporting custom domains with your network requester It is easy to add new domains and services to your network requester - simply find out which endpoints (both URLs and raw IP addresses are supported) you need to whitelist, and then add these endpoints to your `allowed.list`. +> In order to keep things more organised, you can now use comments in the `allow.list` like the example at the top of this page. + How to go about this? Have a look in your nym-network-requester config directory: ``` From a1a2f37fce1ffa8fb60f249602b9fb5ba2e4ba1e Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 13:56:47 +0200 Subject: [PATCH 47/59] included url --- documentation/docs/src/nodes/network-requester-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/src/nodes/network-requester-setup.md b/documentation/docs/src/nodes/network-requester-setup.md index ccea6bfc0f..6fe3ef7971 100644 --- a/documentation/docs/src/nodes/network-requester-setup.md +++ b/documentation/docs/src/nodes/network-requester-setup.md @@ -237,7 +237,7 @@ To make things a bit less stressful for administrators, the Network Requester dr ### Global vs local allow lists Your Network Requester will check for a domain against 2 lists before allowing traffic through for a particular domain or IP. -* The first list is the default list on the [nymtech.net server](). Your Requester will not check against this list every time, but instead will keep a record of accepted domains in memory. +* The first list is the default list on the [nymtech.net server](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt). Your Requester will not check against this list every time, but instead will keep a record of accepted domains in memory. * The second is the local `allowed.list` file. From 7d6d8669b0e684d306edf863ce19fa68d8d8b113 Mon Sep 17 00:00:00 2001 From: Pierre Dommerc Date: Thu, 20 Jul 2023 13:17:49 +0200 Subject: [PATCH 48/59] feat(nc-desktop): add sentry to backend (#3652) --- nym-connect/desktop/Cargo.lock | 11 +++++++++++ nym-connect/desktop/src-tauri/src/main.rs | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 5f48b27bd0..6287fadf38 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2596,6 +2596,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "html5ever" version = "0.25.2" diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index 8449cb3973..dca53ef4a9 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -27,6 +27,10 @@ mod state; mod tasks; mod window; +// TODO DSN shouldn't be hardcoded +const SENTRY_DSN: &str = + "https://68a2c55113ed47aaa30b9899039b0799@o967446.ingest.sentry.io/4505483113594880"; + fn main() { dotenvy::dotenv().ok(); setup_env(None); From a0b41db22d96084defd14ce602ea62125b6e400b Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 19 Jul 2023 11:57:21 +0200 Subject: [PATCH 49/59] added rust sdk surb example --- sdk/rust/nym-sdk/examples/surb-reply.rs | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 sdk/rust/nym-sdk/examples/surb-reply.rs diff --git a/sdk/rust/nym-sdk/examples/surb-reply.rs b/sdk/rust/nym-sdk/examples/surb-reply.rs new file mode 100644 index 0000000000..dae17f8251 --- /dev/null +++ b/sdk/rust/nym-sdk/examples/surb-reply.rs @@ -0,0 +1,64 @@ +use nym_sdk::mixnet::{ + AnonymousSenderTag, MixnetClient, MixnetClientBuilder, ReconstructedMessage, StoragePaths, +}; +use std::path::PathBuf; + +#[tokio::main] +async fn main() { + nym_bin_common::logging::setup_logging(); + + // Specify some config options + let config_dir = PathBuf::from("/tmp/surb-example-client"); + let storage_paths = StoragePaths::new_from_dir(&config_dir).unwrap(); + + // Create the client with a storage backend, and enable it by giving it some paths. If keys + // exists at these paths, they will be loaded, otherwise they will be generated. + let client = MixnetClientBuilder::new_with_default_storage(storage_paths) + .await + .unwrap() + .build() + .await + .unwrap(); + + // Now we connect to the mixnet, using keys now stored in the paths provided. + let mut client = client.connect_to_mixnet().await.unwrap(); + + // Be able to get our client address + let our_address = client.nym_address(); + println!("\nOur client nym address is: {our_address}"); + + // Send a message through the mixnet to ourselves using our nym address + client.send_str(*our_address, "hello there").await; + + // we're going to parse the sender_tag (AnonymousSenderTag) from the incoming message and use it to 'reply' to ourselves instead of our Nym address. + // we know there will be a sender_tag since the sdk sends SURBs along with messages by default. + println!("Waiting for message\n"); + + // get the actual message - discard the empty vec sent along with a potential SURB topup request + let mut message: Vec = Vec::new(); + while let Some(new_message) = client.wait_for_messages().await { + if new_message.is_empty() { + continue; + } + message = new_message; + break; + } + + let mut parsed = String::new(); + if let Some(r) = message.iter().next() { + parsed = String::from_utf8(r.message.clone()).unwrap(); + } + // parse sender_tag: we will use this to reply to sender without needing their Nym address + let return_recipient: AnonymousSenderTag = message[0].sender_tag.unwrap(); + println!("\nReceived the following message: {} \nfrom sender with surb bucket {}", parsed, return_recipient); + + // reply to self with it: note we use `send_str_reply` instead of `send_str` + println!("Replying with using SURBs"); + client.send_str_reply(return_recipient, "hi an0n!").await; + + println!("Waiting for message (once you see it, ctrl-c to exit)\n"); + client + .on_messages(|msg| println!("\nReceived: {}", String::from_utf8_lossy(&msg.message))) + .await; + +} \ No newline at end of file From d8a44cd9c1bfc0249ca7b9b3479f30cc98b5be37 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 21 Jul 2023 14:04:33 +0200 Subject: [PATCH 50/59] added reply with surbs example to rust sdk examples dir --- sdk/rust/nym-sdk/examples/surb-reply.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/rust/nym-sdk/examples/surb-reply.rs b/sdk/rust/nym-sdk/examples/surb-reply.rs index dae17f8251..c7f700cdb1 100644 --- a/sdk/rust/nym-sdk/examples/surb-reply.rs +++ b/sdk/rust/nym-sdk/examples/surb-reply.rs @@ -1,5 +1,5 @@ use nym_sdk::mixnet::{ - AnonymousSenderTag, MixnetClient, MixnetClientBuilder, ReconstructedMessage, StoragePaths, + AnonymousSenderTag, MixnetClientBuilder, ReconstructedMessage, StoragePaths, }; use std::path::PathBuf; @@ -8,7 +8,7 @@ async fn main() { nym_bin_common::logging::setup_logging(); // Specify some config options - let config_dir = PathBuf::from("/tmp/surb-example-client"); + let config_dir = PathBuf::from("/tmp/surb-example"); let storage_paths = StoragePaths::new_from_dir(&config_dir).unwrap(); // Create the client with a storage backend, and enable it by giving it some paths. If keys From 2fe5401a38875fc7feae6f4b93768154ce5ecd7c Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 21 Jul 2023 14:11:22 +0200 Subject: [PATCH 51/59] ran fmt --- sdk/rust/nym-sdk/examples/surb-reply.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sdk/rust/nym-sdk/examples/surb-reply.rs b/sdk/rust/nym-sdk/examples/surb-reply.rs index c7f700cdb1..5edec592e1 100644 --- a/sdk/rust/nym-sdk/examples/surb-reply.rs +++ b/sdk/rust/nym-sdk/examples/surb-reply.rs @@ -1,7 +1,7 @@ use nym_sdk::mixnet::{ AnonymousSenderTag, MixnetClientBuilder, ReconstructedMessage, StoragePaths, }; -use std::path::PathBuf; +use std::path::PathBuf; #[tokio::main] async fn main() { @@ -25,13 +25,13 @@ async fn main() { // Be able to get our client address let our_address = client.nym_address(); - println!("\nOur client nym address is: {our_address}"); + println!("\nOur client nym address is: {our_address}"); // Send a message through the mixnet to ourselves using our nym address client.send_str(*our_address, "hello there").await; - // we're going to parse the sender_tag (AnonymousSenderTag) from the incoming message and use it to 'reply' to ourselves instead of our Nym address. - // we know there will be a sender_tag since the sdk sends SURBs along with messages by default. + // we're going to parse the sender_tag (AnonymousSenderTag) from the incoming message and use it to 'reply' to ourselves instead of our Nym address. + // we know there will be a sender_tag since the sdk sends SURBs along with messages by default. println!("Waiting for message\n"); // get the actual message - discard the empty vec sent along with a potential SURB topup request @@ -48,17 +48,19 @@ async fn main() { if let Some(r) = message.iter().next() { parsed = String::from_utf8(r.message.clone()).unwrap(); } - // parse sender_tag: we will use this to reply to sender without needing their Nym address + // parse sender_tag: we will use this to reply to sender without needing their Nym address let return_recipient: AnonymousSenderTag = message[0].sender_tag.unwrap(); - println!("\nReceived the following message: {} \nfrom sender with surb bucket {}", parsed, return_recipient); + println!( + "\nReceived the following message: {} \nfrom sender with surb bucket {}", + parsed, return_recipient + ); // reply to self with it: note we use `send_str_reply` instead of `send_str` - println!("Replying with using SURBs"); - client.send_str_reply(return_recipient, "hi an0n!").await; + println!("Replying with using SURBs"); + client.send_str_reply(return_recipient, "hi an0n!").await; println!("Waiting for message (once you see it, ctrl-c to exit)\n"); client .on_messages(|msg| println!("\nReceived: {}", String::from_utf8_lossy(&msg.message))) .await; - -} \ No newline at end of file +} From 03300a859e52ef8d0d3fcd792908d2579b02faef Mon Sep 17 00:00:00 2001 From: pierre Date: Fri, 21 Jul 2023 15:56:08 +0200 Subject: [PATCH 52/59] build(nc-desktop): sentry dsn as env var --- nym-connect/desktop/src-tauri/src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index dca53ef4a9..12c7ad06ac 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -3,6 +3,7 @@ windows_subsystem = "windows" )] +use std::env; use std::sync::Arc; use nym_config::defaults::setup_env; @@ -27,10 +28,6 @@ mod state; mod tasks; mod window; -// TODO DSN shouldn't be hardcoded -const SENTRY_DSN: &str = - "https://68a2c55113ed47aaa30b9899039b0799@o967446.ingest.sentry.io/4505483113594880"; - fn main() { dotenvy::dotenv().ok(); setup_env(None); From c38c5c2f0d4b5b6d750ee284622dfe36d1a6186b Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Sun, 23 Jul 2023 12:00:39 +0200 Subject: [PATCH 53/59] fixed clippy warning --- sdk/rust/nym-sdk/examples/surb-reply.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/rust/nym-sdk/examples/surb-reply.rs b/sdk/rust/nym-sdk/examples/surb-reply.rs index 5edec592e1..38c7e8257a 100644 --- a/sdk/rust/nym-sdk/examples/surb-reply.rs +++ b/sdk/rust/nym-sdk/examples/surb-reply.rs @@ -45,7 +45,7 @@ async fn main() { } let mut parsed = String::new(); - if let Some(r) = message.iter().next() { + if let Some(r) = message.first() { parsed = String::from_utf8(r.message.clone()).unwrap(); } // parse sender_tag: we will use this to reply to sender without needing their Nym address From 8a1ed12f582db62a323f1a38b0c09c73aad39445 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Tue, 25 Jul 2023 10:52:17 +0200 Subject: [PATCH 54/59] bump versions for NC --- nym-connect/desktop/CHANGELOG.md | 8 ++++++++ nym-connect/desktop/package.json | 4 ++-- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-connect/desktop/src-tauri/tauri.conf.json | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/nym-connect/desktop/CHANGELOG.md b/nym-connect/desktop/CHANGELOG.md index 174b5e938d..55c9d83a20 100644 --- a/nym-connect/desktop/CHANGELOG.md +++ b/nym-connect/desktop/CHANGELOG.md @@ -2,6 +2,14 @@ ## [Unreleased] +## [1.1.15] (2023-07-25) + +- NC Desktop - remove sentry DSN from code ([#3694]) +- NC - Add Alephium wallet in the supported app list ([#3681]) + +[#3694]: https://github.com/nymtech/nym/issues/3694 +[#3681]: https://github.com/nymtech/nym/issues/3681 + ## [v1.1.14] (2023-07-04) - Nym connect fails to start when encountering an old config version ([#3588]) diff --git a/nym-connect/desktop/package.json b/nym-connect/desktop/package.json index 60ea3b4830..626b415b8f 100644 --- a/nym-connect/desktop/package.json +++ b/nym-connect/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.13", + "version": "1.1.15", "main": "index.js", "license": "MIT", "scripts": { @@ -115,4 +115,4 @@ "webpack-merge": "^5.8.0", "yaml-loader": "^0.8.0" } -} +} \ No newline at end of file diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index c3c1b0a895..e3bd49cb41 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.13" +version = "1.1.15" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-connect/desktop/src-tauri/tauri.conf.json b/nym-connect/desktop/src-tauri/tauri.conf.json index 9b62f46169..b95859ca53 100644 --- a/nym-connect/desktop/src-tauri/tauri.conf.json +++ b/nym-connect/desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.14" + "version": "1.1.15" }, "build": { "distDir": "../dist", @@ -86,4 +86,4 @@ "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'" } } -} +} \ No newline at end of file From a0408b74dc6f1040562f463d204d148082a7a442 Mon Sep 17 00:00:00 2001 From: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com> Date: Tue, 25 Jul 2023 13:45:32 +0200 Subject: [PATCH 55/59] Update nym-connect-publish-macos.yml (#3705) * Update nym-connect-publish-macos.yml install wasm and build * Update nym-connect-publish-macos.yml use the correct download --- .github/workflows/nym-connect-publish-macos.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index 9f103aeb11..c75000ec35 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -31,10 +31,20 @@ jobs: uses: actions/setup-node@v3 with: node-version: 18 + - name: Install Rust stable uses: actions-rs/toolchain@v1 with: toolchain: stable + target: wasm32-unknown-unknown + + - name: Install wasm-pack + run: | + export WASM_PACK_VERSION="v0.12.1" + curl -LO https://github.com/rustwasm/wasm-pack/releases/download/${WASM_PACK_VERSION}/wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz + tar xvzf wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz -C $HOME/.cargo/bin --strip-components=1 + rm wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz + - name: Install the Apple developer certificate for code signing env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} From 4c9727b1ef03d00e7d6941ac93e2a3dd83a16067 Mon Sep 17 00:00:00 2001 From: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:40:46 +0200 Subject: [PATCH 56/59] Update nym-connect-publish-ubuntu.yml (#3706) * Update nym-connect-publish-ubuntu.yml * Update nym-connect-publish-ubuntu.yml * Update nym-connect-publish-macos.yml * Update nym-connect-publish-windows10.yml --- .github/workflows/nym-connect-publish-macos.yml | 7 ++++--- .github/workflows/nym-connect-publish-ubuntu.yml | 8 ++++---- .github/workflows/nym-connect-publish-windows10.yml | 7 ++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index c75000ec35..863811b3ec 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -115,9 +115,10 @@ jobs: - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_$version_x64.dmg" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-connect-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT" push-release-data: diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index fb0c0eec4b..31fd92c612 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -82,11 +82,11 @@ jobs: - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_$version_amd64.AppImage" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-connect-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${version}_amd64.AppImage" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/appimage/nym-connect_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT" - push-release-data: if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} uses: ./.github/workflows/push-release-data.yml diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index ca6f6aef01..3b10806ffe 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -101,9 +101,10 @@ jobs: - id: release-info name: Prepare release info run: | - semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}" - echo "version=$semver" >> "$GITHUB_OUTPUT" - echo "filename=nym-connect_$version_x64_en-US.msi" >> "$GITHUB_OUTPUT" + ref=${{ github.ref_name }} + semver="${ref##nym-connect-}" && semver="${semver##v}" + echo "version=${semver}" >> "$GITHUB_OUTPUT" + echo "filename=nym-connect_${version}_x64_en-US.msi" >> "$GITHUB_OUTPUT" echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/msi/nym-connect_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT" push-release-data: From 557bfa7b3463faf83a979d57eea7038e04835b67 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:36:59 +0200 Subject: [PATCH 57/59] Update CHANGELOG.md --- nym-connect/desktop/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-connect/desktop/CHANGELOG.md b/nym-connect/desktop/CHANGELOG.md index 55c9d83a20..1149c3b227 100644 --- a/nym-connect/desktop/CHANGELOG.md +++ b/nym-connect/desktop/CHANGELOG.md @@ -2,7 +2,7 @@ ## [Unreleased] -## [1.1.15] (2023-07-25) +## [v1.1.15] (2023-07-25) - NC Desktop - remove sentry DSN from code ([#3694]) - NC - Add Alephium wallet in the supported app list ([#3681]) From 109fb96fcaf5561118ccf7078ab774b7c7fdf585 Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 25 Jul 2023 15:47:24 +0200 Subject: [PATCH 58/59] fix workflows --- .github/workflows/nym-connect-publish-macos.yml | 4 ++-- .github/workflows/nym-connect-publish-ubuntu.yml | 2 +- .github/workflows/nym-connect-publish-windows10.yml | 2 +- .github/workflows/nym-wallet-publish-macos.yml | 2 +- .github/workflows/nym-wallet-publish-ubuntu.yml | 2 +- .github/workflows/nym-wallet-publish-windows10.yml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index 863811b3ec..c8fdefae22 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} @@ -37,7 +37,7 @@ jobs: with: toolchain: stable target: wasm32-unknown-unknown - + - name: Install wasm-pack run: | export WASM_PACK_VERSION="v0.12.1" diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index 31fd92c612..db391aa974 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index 3b10806ffe..52fdaa7cac 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].published_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-macos.yml b/.github/workflows/nym-wallet-publish-macos.yml index 5a87e38d1c..9c45d4c969 100644 --- a/.github/workflows/nym-wallet-publish-macos.yml +++ b/.github/workflows/nym-wallet-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 027908e2f6..2f1f5e282b 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-windows10.yml b/.github/workflows/nym-wallet-publish-windows10.yml index 974de92435..789df149e9 100644 --- a/.github/workflows/nym-wallet-publish-windows10.yml +++ b/.github/workflows/nym-wallet-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} From 1da6ee20584367c3ee04397571ae391f0032e9ba Mon Sep 17 00:00:00 2001 From: pierre Date: Tue, 25 Jul 2023 16:05:01 +0200 Subject: [PATCH 59/59] fix workflows (try) --- .github/workflows/nym-connect-publish-macos.yml | 2 +- .github/workflows/nym-connect-publish-ubuntu.yml | 2 +- .github/workflows/nym-connect-publish-windows10.yml | 2 +- .github/workflows/nym-wallet-publish-macos.yml | 2 +- .github/workflows/nym-wallet-publish-ubuntu.yml | 2 +- .github/workflows/nym-wallet-publish-windows10.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nym-connect-publish-macos.yml b/.github/workflows/nym-connect-publish-macos.yml index c8fdefae22..45dac7e87a 100644 --- a/.github/workflows/nym-connect-publish-macos.yml +++ b/.github/workflows/nym-connect-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-connect-publish-ubuntu.yml b/.github/workflows/nym-connect-publish-ubuntu.yml index db391aa974..cc5e1f3f00 100644 --- a/.github/workflows/nym-connect-publish-ubuntu.yml +++ b/.github/workflows/nym-connect-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-connect-publish-windows10.yml b/.github/workflows/nym-connect-publish-windows10.yml index 52fdaa7cac..1b4b1be2cc 100644 --- a/.github/workflows/nym-connect-publish-windows10.yml +++ b/.github/workflows/nym-connect-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-macos.yml b/.github/workflows/nym-wallet-publish-macos.yml index 9c45d4c969..408a3b7406 100644 --- a/.github/workflows/nym-wallet-publish-macos.yml +++ b/.github/workflows/nym-wallet-publish-macos.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-ubuntu.yml b/.github/workflows/nym-wallet-publish-ubuntu.yml index 2f1f5e282b..9e9ee904cd 100644 --- a/.github/workflows/nym-wallet-publish-ubuntu.yml +++ b/.github/workflows/nym-wallet-publish-ubuntu.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }} diff --git a/.github/workflows/nym-wallet-publish-windows10.yml b/.github/workflows/nym-wallet-publish-windows10.yml index 789df149e9..56a332a75d 100644 --- a/.github/workflows/nym-wallet-publish-windows10.yml +++ b/.github/workflows/nym-wallet-publish-windows10.yml @@ -19,7 +19,7 @@ jobs: outputs: release_id: ${{ steps.create-release.outputs.id }} - release_date: ${{ fromJSON(steps.create-release.outputs.assets[0].created_at) }} + release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }} version: ${{ steps.release-info.outputs.version }} filename: ${{ steps.release-info.outputs.filename }} file_hash: ${{ steps.release-info.outputs.file_hash }}