diff --git a/.github/workflows/network-explorer-api.yml b/.github/workflows/network-explorer-api.yml new file mode 100644 index 0000000000..2ad184be72 --- /dev/null +++ b/.github/workflows/network-explorer-api.yml @@ -0,0 +1,56 @@ +name: CI for Network Explorer API + +on: + workflow_dispatch: + release: + types: [created] + +env: + NETWORK: mainnet + +jobs: + publish-nym: + strategy: + fail-fast: false + matrix: + platform: [ubuntu-latest] + + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v3 + + - name: Install Dependencies (Linux) + run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools + + - name: Check the release tag starts with `nym-explorer-api-` + if: startsWith(github.ref, 'refs/tags/nym-explorer-api-') == false && github.event_name != 'workflow_dispatch' + uses: actions/github-script@v3 + with: + script: | + core.setFailed('Release tag did not start with nym-explorer-api-...') + + - name: Install Rust stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Build all explorer-api + uses: actions-rs/cargo@v1 + with: + command: build + args: --manifest-path explorer-api/Cargo.toml --workspace --release + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: my-artifact + path: | + target/release/explorer-api + retention-days: 30 + + - name: Upload to release based on tag name + uses: softprops/action-gh-release@v1 + if: github.event_name == 'release' + with: + files: | + target/release/explorer-api diff --git a/Makefile b/Makefile index 95d163a7ca..8f5aba2678 100644 --- a/Makefile +++ b/Makefile @@ -92,6 +92,9 @@ build-wallet: build-connect: cargo build --manifest-path nym-connect/Cargo.toml --workspace +build-explorer-api: + cargo build --manifest-path explorer-api/Cargo.toml --workspace + build-wasm-client: cargo build --manifest-path clients/webassembly/Cargo.toml --workspace --target wasm32-unknown-unknown diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index ed415e2622..9e93b9194b 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -10,7 +10,7 @@ pub const MIX_DENOM: DenomDetails = DenomDetails::new("unym", "nym", 6); pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6); pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = - "n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g"; + "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = diff --git a/nym-wallet/nym-wallet-types/src/network.rs b/nym-wallet/nym-wallet-types/src/network.rs index 1be3c80732..7a0e01c527 100644 --- a/nym-wallet/nym-wallet-types/src/network.rs +++ b/nym-wallet/nym-wallet-types/src/network.rs @@ -160,9 +160,9 @@ mod qa { pub(crate) const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6); pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = - "n1frq2hzkjtatsupc6jtyaz67ytydk9nya437q92qg76ny3y8fcnjsw806vg"; - pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g"; + pub(crate) const VESTING_CONTRACT_ADDRESS: &str = + "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = @@ -177,8 +177,8 @@ mod qa { //pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "http://0.0.0.0"; pub(crate) fn validators() -> Vec { vec![ValidatorDetails::new( - "https://adv-epoch-qa-validator.qa.nymte.ch/", - Some("https://adv-epoch-qa-val-api.qa.nymte.ch/api"), + "https://qwerty-validator.qa.nymte.ch/", + Some("https://qwerty-validator-api.qa.nymte.ch/api"), )] } diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index a30e5557cb..00b3ea7196 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -42,7 +42,7 @@ const headers: Header[] = [ header: 'Operator rewards', id: 'operator-rewards', tooltipText: - 'This is your (operator) new rewards including the PM and cost. You can compound your rewards manually every epoch or unbond your node to redeem them.', + 'This is your (operator) rewards including the PM and cost. Rewards are automatically compounded every epoch. You can redeem your rewards at any time.', }, { header: 'No. delegators', diff --git a/nym-wallet/src/pages/balance/vesting.tsx b/nym-wallet/src/pages/balance/vesting.tsx index a3a52a44b1..c58c1454dd 100644 --- a/nym-wallet/src/pages/balance/vesting.tsx +++ b/nym-wallet/src/pages/balance/vesting.tsx @@ -130,16 +130,10 @@ const TokenTransfer = () => { t.palette.nym.text.muted, mt: 2 }}> - Transferable tokens + Unlocked transferable tokens - + {userBalance.tokenAllocation?.spendable || 'n/a'} {clientDetails?.display_mix_denom.toUpperCase()} @@ -167,7 +161,6 @@ export const VestingCard = ({ onTransfer }: { onTransfer: () => Promise }) } Action={ { diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index 4a6097b8da..f576afccd9 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -33,10 +33,17 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { + + + diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/InfoSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/InfoSettings.tsx index 7b85f1c0c2..31e88a0f31 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/InfoSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/InfoSettings.tsx @@ -4,15 +4,20 @@ import { yupResolver } from '@hookform/resolvers/yup'; import { Button, Divider, Typography, TextField, Grid, CircularProgress, Box } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { isMixnode } from 'src/types'; -import { updateMixnodeConfig } from 'src/requests'; +import { simulateUpdateMixnodeConfig, simulateVestingUpdateMixnodeConfig, updateMixnodeConfig } from 'src/requests'; import { TBondedMixnode, TBondedGateway } from 'src/context/bonding'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { bondedInfoParametersValidationSchema } from 'src/components/Bonding/forms/mixnodeValidationSchema'; import { Console } from 'src/utils/console'; import { Alert } from 'src/components/Alert'; +import { vestingUpdateMixnodeConfig } from 'src/requests/vesting'; +import { ConfirmTx } from 'src/components/ConfirmTX'; +import { useGetFee } from 'src/hooks/useGetFee'; +import { LoadingModal } from 'src/components/Modals/LoadingModal'; export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBondedGateway }) => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); + const { getFee, fee, resetFeeState } = useGetFee(); const theme = useTheme(); @@ -33,6 +38,7 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon verlocPort?: number; httpApiPort?: number; }) => { + resetFeeState(); const { host, version, mixPort, verlocPort, httpApiPort } = data; if (host && version && mixPort && verlocPort && httpApiPort) { const MixNodeConfigParams = { @@ -43,7 +49,11 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon version, }; try { - await updateMixnodeConfig(MixNodeConfigParams); + if (bondedNode.proxy) { + await vestingUpdateMixnodeConfig(MixNodeConfigParams); + } else { + await updateMixnodeConfig(MixNodeConfigParams); + } setOpenConfirmationModal(true); } catch (error) { Console.error(error); @@ -53,10 +63,22 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon return ( + {fee && ( + onSubmit(d))} + onPrev={resetFeeState} + onClose={resetFeeState} + /> + )} + {isSubmitting && } - Your changes will be ONLY saved on the display. Remember to change the values on your node’s config file too + Changing these values will ONLY change the data about your node on the blockchain. Remember to change your + node’s config file with the same values too } dismissable @@ -67,16 +89,6 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon Port - (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'), - }} - > - Change profit margin of your node - @@ -120,16 +132,6 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon Host - (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'), - }} - > - Lock wallet after certain time - @@ -151,16 +153,6 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon Version - (t.palette.mode === 'light' ? t.palette.nym.text.muted : 'text.primary'), - }} - > - Lock wallet after certain time - @@ -182,18 +174,24 @@ export const InfoSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBon size="large" variant="contained" disabled={isSubmitting || !isDirty || !isValid} - onClick={handleSubmit((d) => onSubmit(d))} - type="submit" - sx={{ m: 3, width: '320px' }} - endIcon={isSubmitting && } + onClick={handleSubmit((data) => + getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeConfig : simulateUpdateMixnodeConfig, { + host: data.host, + mix_port: data.mixPort, + verloc_port: data.verlocPort, + http_api_port: data.httpApiPort, + version: data.version, + }), + )} + sx={{ m: 3 }} > - Save all display changes + Submit changes to the blockchain diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index ad9b3d03af..aebb21c8c1 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -14,17 +14,27 @@ import { } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types'; +import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { add, format, fromUnixTime } from 'date-fns'; import { isMixnode } from 'src/types'; -import { getCurrentInterval, getPendingIntervalEvents, updateMixnodeCostParams } from 'src/requests'; -import { TBondedMixnode, TBondedGateway } from 'src/context/bonding'; +import { + getCurrentInterval, + getPendingIntervalEvents, + simulateUpdateMixnodeCostParams, + simulateVestingUpdateMixnodeCostParams, + updateMixnodeCostParams, + vestingUpdateMixnodeCostParams, +} from 'src/requests'; +import { TBondedMixnode } from 'src/context/bonding'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { bondedNodeParametersValidationSchema } from 'src/components/Bonding/forms/mixnodeValidationSchema'; import { Console } from 'src/utils/console'; import { Alert } from 'src/components/Alert'; import { ChangeMixCostParams } from 'src/pages/bonding/types'; import { AppContext } from 'src/context'; -import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; +import { useGetFee } from 'src/hooks/useGetFee'; +import { ConfirmTx } from 'src/components/ConfirmTX'; +import { LoadingModal } from 'src/components/Modals/LoadingModal'; export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); @@ -34,6 +44,8 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode const { clientDetails } = useContext(AppContext); const theme = useTheme(); + const { fee, getFee, resetFeeState } = useGetFee(); + const defaultValues = { operatorCost: bondedNode.operatorCost, profitMargin: bondedNode.profitMargin, @@ -96,6 +108,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }, []); const onSubmit = async (data: { operatorCost: { amount: string; denom: CurrencyDenom }; profitMargin: string }) => { + resetFeeState(); if (data.operatorCost && data.profitMargin) { const MixNodeCostParams = { profit_margin_percent: (+data.profitMargin / 100).toString(), @@ -105,7 +118,11 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }, }; try { - await updateMixnodeCostParams(MixNodeCostParams); + if (bondedNode.proxy) { + await vestingUpdateMixnodeCostParams(MixNodeCostParams); + } else { + await updateMixnodeCostParams(MixNodeCostParams); + } await getPendingEvents(); reset(); setOpenConfirmationModal(true); @@ -117,6 +134,17 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode return ( + {fee && ( + onSubmit(d))} + onPrev={resetFeeState} + onClose={resetFeeState} + /> + )} + {isSubmitting && } @@ -129,7 +157,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode /> - + Profit Margin @@ -223,12 +251,16 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode size="large" variant="contained" disabled={isSubmitting || !isDirty || !isValid} - onClick={handleSubmit(onSubmit)} + onClick={handleSubmit((data) => { + getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeCostParams : simulateUpdateMixnodeCostParams, { + profit_margin_percent: (+data.profitMargin / 100).toString(), + interval_operating_cost: data.operatorCost, + }); + })} type="submit" - sx={{ m: 3, width: '320px' }} - endIcon={isSubmitting && } + sx={{ m: 3 }} > - Save all display changes + Submit changes to the blockchain @@ -236,7 +268,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode open={openConfirmationModal} header="Your changes will take place in the next interval" - okLabel="close" + okLabel="Close" hideCloseIcon displayInfoIcon onOk={async () => { @@ -256,7 +288,6 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode textAlign: 'center', color: theme.palette.nym.nymWallet.text.blue, fontSize: 16, - textTransform: 'capitalize', }} subHeaderStyles={{ m: 0, diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 71046109da..e6cb277610 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -23,15 +23,19 @@ const ENABLE_STATISTICS: &str = "enable-statistics"; #[derive(Args)] struct Run { /// Specifies whether this network requester should run in 'open-proxy' mode + #[clap(long)] open_proxy: bool, /// Websocket port to bind to + #[clap(long)] websocket_port: Option, /// Enable service anonymized statistics that get sent to a statistics aggregator server + #[clap(long)] enable_statistics: bool, /// Mixnet client address where a statistics aggregator is running. The default value is a Nym aggregator client + #[clap(long)] statistics_recipient: Option, }