From fe223b5a6012cb5e1adeb5a3f3d0b6f3a3eb276f Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 16 Sep 2022 12:33:56 +0100 Subject: [PATCH] apy playground ui update calc button style validator-api-client and wallet: compute mixnode reward estimation --- .../validator-client/src/nym_api/mod.rs | 28 +++- .../validator-client/src/nym_api/routes.rs | 1 + nym-wallet/src-tauri/src/main.rs | 1 + .../src/operations/nym_api/status.rs | 22 ++- .../node-settings/apy-playground/index.tsx | 151 ++++++++++++++++++ ts-packages/mui-theme/src/theme/theme.ts | 1 + 6 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 nym-wallet/src/pages/bonding/node-settings/apy-playground/index.tsx diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index 00fd839d4e..f464633fdd 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -9,10 +9,11 @@ use nym_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; use nym_api_requests::models::{ - GatewayCoreStatusResponse, GatewayStatusReportResponse, GatewayUptimeHistoryResponse, - InclusionProbabilityResponse, MixNodeBondAnnotated, MixnodeCoreStatusResponse, - MixnodeStatusReportResponse, MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RequestError, - RewardEstimationResponse, StakeSaturationResponse, UptimeResponse, + ComputeRewardEstParam, GatewayCoreStatusResponse, GatewayStatusReportResponse, + GatewayUptimeHistoryResponse, InclusionProbabilityResponse, MixNodeBondAnnotated, + MixnodeCoreStatusResponse, MixnodeStatusReportResponse, MixnodeStatusResponse, + MixnodeUptimeHistoryResponse, RequestError, RewardEstimationResponse, StakeSaturationResponse, + UptimeResponse, }; use reqwest::Response; use serde::{Deserialize, Serialize}; @@ -361,6 +362,25 @@ impl Client { .await } + pub async fn compute_mixnode_reward_estimation( + &self, + identity: IdentityKeyRef<'_>, + request_body: &ComputeRewardEstParam, + ) -> Result { + self.post_validator_api( + &[ + routes::API_VERSION, + routes::STATUS_ROUTES, + routes::MIXNODE, + identity, + routes::COMPUTE_REWARD_ESTIMATION, + ], + NO_PARAMS, + request_body, + ) + .await + } + pub async fn get_mixnode_stake_saturation( &self, mix_id: MixId, diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index 5b3d1c266d..cd8a16047a 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -28,6 +28,7 @@ pub const STATUS: &str = "status"; pub const REPORT: &str = "report"; pub const HISTORY: &str = "history"; pub const REWARD_ESTIMATION: &str = "reward-estimation"; +pub const COMPUTE_REWARD_ESTIMATION: &str = "compute-reward-estimation"; pub const AVG_UPTIME: &str = "avg_uptime"; pub const STAKE_SATURATION: &str = "stake-saturation"; pub const INCLUSION_CHANCE: &str = "inclusion-probability"; diff --git a/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index 63e2a43e4f..8da3d69051 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -99,6 +99,7 @@ fn main() { 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, nym_api::status::gateway_core_node_status, nym_api::status::mixnode_core_node_status, nym_api::status::mixnode_inclusion_probability, diff --git a/nym-wallet/src-tauri/src/operations/nym_api/status.rs b/nym-wallet/src-tauri/src/operations/nym_api/status.rs index 16c83cfb67..135bf0ee21 100644 --- a/nym-wallet/src-tauri/src/operations/nym_api/status.rs +++ b/nym-wallet/src-tauri/src/operations/nym_api/status.rs @@ -8,7 +8,7 @@ use mixnet_contract_common::{IdentityKeyRef, MixId}; use validator_client::models::{ GatewayCoreStatusResponse, GatewayStatusReportResponse, InclusionProbabilityResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, RewardEstimationResponse, - StakeSaturationResponse, + StakeSaturationResponse, ComputeRewardEstParam }; #[tauri::command] @@ -59,6 +59,26 @@ pub async fn mixnode_reward_estimation( .await?) } +#[tauri::command] +pub async fn compute_mixnode_reward_estimation( + identity: &str, + uptime: Option, + is_active: Option, + pledge_amount: Option, + total_delegation: Option, + state: tauri::State<'_, WalletState>, +) -> Result { + let request_body = ComputeRewardEstParam { + uptime, + is_active, + pledge_amount, + total_delegation, + }; + Ok(api_client!(state) + .compute_mixnode_reward_estimation(identity, &request_body) + .await?) +} + #[tauri::command] pub async fn mixnode_stake_saturation( mix_id: MixId, diff --git a/nym-wallet/src/pages/bonding/node-settings/apy-playground/index.tsx b/nym-wallet/src/pages/bonding/node-settings/apy-playground/index.tsx new file mode 100644 index 0000000000..9a51675955 --- /dev/null +++ b/nym-wallet/src/pages/bonding/node-settings/apy-playground/index.tsx @@ -0,0 +1,151 @@ +import React, { useState } from 'react'; +import { + Box, + Button, + Card, + CardActions, + CardContent, + CardHeader, + Divider, + Grid, + Stack, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + TextField, + Typography, +} from '@mui/material'; + +const tableHeader = [ + { title: 'Estimated rewards', bold: true }, + { title: 'Per day' }, + { title: 'Per month' }, + { title: 'Per year' }, +]; + +const tableRows = [ + { title: 'Total node reward', perDay: '10 NYM', perMonth: '300 NYM', perYear: '3600 NYM' }, + { title: 'Operator rewards', perDay: '10 NYM', perMonth: '300 NYM', perYear: '3600 NYM' }, + { title: 'Delegator rewards', perDay: '10 NYM', perMonth: '300 NYM', perYear: '3600 NYM' }, +]; + +const ResultsTable = () => ( + + + + + + + {tableHeader.map((header) => ( + + {header.title} + + ))} + + + + {tableRows.map((row) => ( + + {row.title} + {row.perDay} + {row.perMonth} + {row.perYear} + + ))} + +
+
+
+
+); + +const NodeDetails = ({ saturation, selectionProbability }: { saturation: number; selectionProbability: string }) => ( + + + + Stake saturation + {saturation}% + + + + Selection probability + {selectionProbability} + + + +); + +export const ApyPlayground = () => { + const [inputValues, setInputValues] = useState([ + { label: 'Profit margin', isPercentage: true, value: '' }, + { label: 'Operator cost', value: '' }, + { label: 'Bond', value: '' }, + { label: 'Delegations', value: '' }, + { label: 'Uptime', isPercentage: true, value: '' }, + ]); + + const handleInputChange = (e: React.ChangeEvent) => { + setInputValues((current) => [ + ...current.map((input) => (input.label === e.target.name ? { ...input, value: e.target.value } : input)), + ]); + }; + + const handleCalculate = () => console.log(inputValues); + + return ( + + + Playground + + + This is your parameters playground - change the parameters below to see the node specific estimations in the + table + + + + Estimation calculator + + } + /> + + + {inputValues.map((input) => ( + + {input.isPercentage ? '%' : 'NYM'} + ), + }} + /> + + ))} + + + + + + + + + + + + + + + + ); +}; diff --git a/ts-packages/mui-theme/src/theme/theme.ts b/ts-packages/mui-theme/src/theme/theme.ts index a12e706e9e..bb4dcae533 100644 --- a/ts-packages/mui-theme/src/theme/theme.ts +++ b/ts-packages/mui-theme/src/theme/theme.ts @@ -84,6 +84,7 @@ export const getDesignTokens = (mode: PaletteMode): ThemeOptions => { ].join(','), fontSize: 14, fontWeightRegular: 500, + fontWeightMedium: 600, button: { textTransform: 'none', fontWeight: '600',