diff --git a/nym-wallet/src/components/CopyToClipboard.tsx b/nym-wallet/src/components/CopyToClipboard.tsx
index 453a2ce382..8df15668a8 100644
--- a/nym-wallet/src/components/CopyToClipboard.tsx
+++ b/nym-wallet/src/components/CopyToClipboard.tsx
@@ -36,7 +36,7 @@ export const CopyToClipboard = ({ text = '', iconButton }: { text?: string; icon
color: 'text.primary',
}}
>
- {!copied ? : }
+ {!copied ? : }
);
diff --git a/nym-wallet/src/context/bonding.tsx b/nym-wallet/src/context/bonding.tsx
index d7a584e533..33f56a3859 100644
--- a/nym-wallet/src/context/bonding.tsx
+++ b/nym-wallet/src/context/bonding.tsx
@@ -1,4 +1,4 @@
-import { MajorCurrencyAmount, TransactionExecuteResult } from '@nymproject/types';
+import { MajorCurrencyAmount, MixnodeStatus, TransactionExecuteResult } from '@nymproject/types';
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import type { Network } from 'src/types';
import { TBondGatewayArgs, TBondMixNodeArgs } from 'src/types';
@@ -11,6 +11,26 @@ import {
unbondMixNode as unbondMixNodeRequest,
} from '../requests';
+/* const bounded: BondedMixnode = {
+ bond: { denom: 'NYM', amount: '1234' },
+ key: 'B2Xx4haarLWMajX8w259oHjtRZsC7nHwagbWrJNiA3QC',
+ delegators: 123,
+ ip: '1.2.34.5',
+ nodeRewards: { denom: 'NYM', amount: '123' },
+ operatorRewards: { denom: 'NYM', amount: '12' },
+ profitMargin: 10,
+ stake: { denom: 'NYM', amount: '99' },
+ stakeSaturation: 99,
+ status: 'active',
+}; */
+
+const bounded: BondedMixnode | BondedGateway = {
+ bond: { denom: 'NYM', amount: '1234' },
+ key: 'B2Xx4haarLWMajX8w259oHjtRZsC7nHwagbWrJNiA3QC',
+ ip: '1.2.34.5',
+ location: 'France',
+};
+
// TODO temporary type for bonded mixnode data
export interface BondedMixnode {
key: string;
@@ -22,6 +42,7 @@ export interface BondedMixnode {
nodeRewards: MajorCurrencyAmount;
operatorRewards: MajorCurrencyAmount;
delegators: number;
+ status: MixnodeStatus;
}
// TODO temporary type for bonded gateway data
@@ -89,17 +110,6 @@ export const BondingContextProvider = ({
};
const refresh = useCallback(async () => {
- const bounded: BondedMixnode = {
- bond: { denom: 'NYM', amount: '1234' },
- key: 'B2Xx4haarLWMajX8w259oHjtRZsC7nHwagbWrJNiA3QC',
- delegators: 123,
- ip: '1.2.34.5',
- nodeRewards: { denom: 'NYM', amount: '123' },
- operatorRewards: { denom: 'NYM', amount: '12' },
- profitMargin: 10,
- stake: { denom: 'NYM', amount: '99' },
- stakeSaturation: 99,
- };
// TODO fetch bondedMixnode and bondedGatway via tauri dedicated requests
/* try {
bounded = await fetchBondingData();
@@ -192,6 +202,7 @@ export const BondingContextProvider = ({
error,
bondMixnode,
bondedMixnode,
+ bondedGateway,
bondGateway,
unbondMixnode,
unbondGateway,
diff --git a/nym-wallet/src/context/mocks/bonding.tsx b/nym-wallet/src/context/mocks/bonding.tsx
index 0fddce84a7..1a87713c37 100644
--- a/nym-wallet/src/context/mocks/bonding.tsx
+++ b/nym-wallet/src/context/mocks/bonding.tsx
@@ -16,6 +16,7 @@ const bondedMixnodeMock: BondedMixnode = {
nodeRewards: { denom: 'NYM', amount: '1234' },
operatorRewards: { denom: 'NYM', amount: '1234' },
delegators: 5423,
+ status: 'active',
};
const bondedGatewayMock: BondedGateway = {
diff --git a/nym-wallet/src/pages/bonding/BondedNodeCard.tsx b/nym-wallet/src/pages/bonding/BondedNodeCard.tsx
new file mode 100644
index 0000000000..148172c8a9
--- /dev/null
+++ b/nym-wallet/src/pages/bonding/BondedNodeCard.tsx
@@ -0,0 +1,86 @@
+import * as React from 'react';
+import { Card, CardContent, CardHeader, Stack, Typography } from '@mui/material';
+import { MixnodeStatus } from '@nymproject/types';
+import { CheckCircleOutline, CircleOutlined, PauseCircleOutlined } from '@mui/icons-material';
+import { CopyToClipboard } from '../../components';
+import { splice } from '../../utils';
+
+interface Props {
+ children?: React.ReactNode;
+ title: string;
+ identityKey: string;
+ status?: MixnodeStatus;
+ action?: React.ReactNode;
+}
+
+const IdentityKey = ({ identityKey }: { identityKey: string }) => (
+
+ {splice(6, identityKey)}
+
+
+);
+
+export const getNodeStatus = ({ status }: { status: MixnodeStatus }) => {
+ switch (status) {
+ case 'active':
+ return (
+
+ Active
+
+ );
+ case 'standby':
+ return (
+
+ Standby
+
+ );
+ case 'inactive':
+ return (
+
+ Inactive
+
+ );
+ case 'not_found':
+ return (
+
+ Not found
+
+ );
+ default:
+ return null;
+ }
+};
+
+const BondedNodeCard = (props: Props) => {
+ const { title: rawTitle, identityKey, status: rawStatus, action, children } = props;
+ let title: string | React.ReactNode = (
+
+ {rawTitle}
+
+ );
+ if (rawStatus) {
+ title = (
+
+
+ {rawTitle}
+
+ {getNodeStatus({ status: rawStatus })}
+
+ );
+ }
+
+ return (
+
+ }
+ action={action}
+ disableTypography
+ sx={{ pb: 0 }}
+ />
+ {children}
+
+ );
+};
+
+export default BondedNodeCard;
diff --git a/nym-wallet/src/pages/bonding/GatewayCard.tsx b/nym-wallet/src/pages/bonding/GatewayCard.tsx
index 08794d4f82..12716866a5 100644
--- a/nym-wallet/src/pages/bonding/GatewayCard.tsx
+++ b/nym-wallet/src/pages/bonding/GatewayCard.tsx
@@ -1,11 +1,61 @@
-import React from 'react';
-import { Grid } from '@mui/material';
+import React, { useMemo } from 'react';
+import { IconButton } from '@mui/material';
+import { MoreVert } from '@mui/icons-material';
+import { useTheme } from '@mui/material/styles';
import { NymCard } from '../../components';
+import { BondedGateway } from '../../context';
+import { Cell, Header, NodeTable } from './NodeTable';
+import BondedNodeCard from './BondedNodeCard';
+import { bondGateway } from '../../requests';
-export const GatewayCard = () => (
-
-
- bonded gateway data table
-
-
-);
+const headers: Header[] = [
+ {
+ header: 'IP',
+ id: 'ip-header',
+ sx: { pl: 0 },
+ },
+ {
+ header: 'Bond',
+ id: 'bond-header',
+ },
+ {
+ id: 'menu-button',
+ size: 'small',
+ sx: { pr: 0 },
+ },
+];
+
+export const GatewayCard = ({ gateway }: { gateway: BondedGateway }) => {
+ const { ip, bond } = gateway;
+ const theme = useTheme();
+ const cells: Cell[] = useMemo(
+ () => [
+ {
+ cell: ip,
+ id: 'ip-cell',
+ sx: { pl: 0 },
+ },
+ {
+ cell: `${bond.amount} ${bond.denom}`,
+ id: 'bond-cell',
+ },
+ {
+ cell: (
+
+
+
+ ),
+ id: 'menu-button-cell',
+ align: 'center',
+ size: 'small',
+ sx: { pr: 0 },
+ },
+ ],
+ [gateway, theme],
+ );
+ return (
+
+
+
+ );
+};
diff --git a/nym-wallet/src/pages/bonding/MixnodeCard.tsx b/nym-wallet/src/pages/bonding/MixnodeCard.tsx
index ba38302f6a..a9875f60eb 100644
--- a/nym-wallet/src/pages/bonding/MixnodeCard.tsx
+++ b/nym-wallet/src/pages/bonding/MixnodeCard.tsx
@@ -1,10 +1,12 @@
import React, { useMemo } from 'react';
-import { IconButton, Typography } from '@mui/material';
+import { Button, IconButton, Typography } from '@mui/material';
import { MoreVert } from '@mui/icons-material';
+import { useTheme } from '@mui/material/styles';
import { Link } from '@nymproject/react/link/Link';
-import { NymCard } from '../../components';
import { BondedMixnode } from '../../context';
+import { Node as NodeIcon } from '../../svg-icons/node';
import { Cell, Header, NodeTable } from './NodeTable';
+import BondedNodeCard from './BondedNodeCard';
const headers: Header[] = [
{
@@ -51,6 +53,7 @@ const headers: Header[] = [
export const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
const { stake, bond, stakeSaturation, profitMargin, nodeRewards, operatorRewards, delegators } = mixnode;
+ const theme = useTheme();
const cells: Cell[] = useMemo(
() => [
{
@@ -65,6 +68,7 @@ export const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
{
cell: `${stakeSaturation}%`,
id: 'stake-saturation-cell',
+ color: stakeSaturation > 100 ? theme.palette.nym.nymWallet.selectionChance.underModerate : undefined,
},
{
cell: `${profitMargin}%`,
@@ -94,10 +98,29 @@ export const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
sx: { pr: 0 },
},
],
- [mixnode],
+ [mixnode, theme],
);
return (
-
+ }
+ >
+ Node settings
+
+ }
+ >
Check more stats of your node on the{' '}
@@ -105,6 +128,6 @@ export const MixnodeCard = ({ mixnode }: { mixnode: BondedMixnode }) => {
explorer
-
+
);
};
diff --git a/nym-wallet/src/pages/bonding/NodeTable.tsx b/nym-wallet/src/pages/bonding/NodeTable.tsx
index 4dcc45fe29..5af3e560fa 100644
--- a/nym-wallet/src/pages/bonding/NodeTable.tsx
+++ b/nym-wallet/src/pages/bonding/NodeTable.tsx
@@ -25,7 +25,7 @@ export interface TableCell {
export type TableHeader = TableCell & { tooltip?: React.ReactNode };
const CellHeader = ({ children, tooltip, sx, size, align, color }: TableHeader) => (
-
+
{tooltip ? (
@@ -40,7 +40,7 @@ const CellHeader = ({ children, tooltip, sx, size, align, color }: TableHeader)
);
const CellValue = ({ children, align, size, color, sx }: TableCell) => (
-
+
{children}
);
diff --git a/nym-wallet/src/pages/bonding/index.tsx b/nym-wallet/src/pages/bonding/index.tsx
index 8a6746a471..32cfa7dbb1 100644
--- a/nym-wallet/src/pages/bonding/index.tsx
+++ b/nym-wallet/src/pages/bonding/index.tsx
@@ -27,6 +27,7 @@ const Bonding = () => {
{bondedMixnode && }
+ {bondedGateway && }
);
diff --git a/nym-wallet/src/theme/mui-theme.d.ts b/nym-wallet/src/theme/mui-theme.d.ts
index 83e2c36d79..3ebdaec69c 100644
--- a/nym-wallet/src/theme/mui-theme.d.ts
+++ b/nym-wallet/src/theme/mui-theme.d.ts
@@ -64,6 +64,17 @@ declare module '@mui/material/styles' {
nav: {
background: string;
};
+ mixnodes: {
+ status: {
+ active: string;
+ standby: string;
+ };
+ };
+ selectionChance: {
+ overModerate: string;
+ moderate: string;
+ underModerate: string;
+ };
}
/**
diff --git a/nym-wallet/src/theme/theme.tsx b/nym-wallet/src/theme/theme.tsx
index 6749d3d864..6cc8adb2c9 100644
--- a/nym-wallet/src/theme/theme.tsx
+++ b/nym-wallet/src/theme/theme.tsx
@@ -56,6 +56,17 @@ const darkMode: NymPaletteVariant = {
nav: {
background: '#292E34',
},
+ mixnodes: {
+ status: {
+ active: '#20D073',
+ standby: '#5FD7EF',
+ },
+ },
+ selectionChance: {
+ overModerate: '#20D073',
+ moderate: '#EBA53D',
+ underModerate: '#DA465B',
+ },
};
const lightMode: NymPaletteVariant = {
@@ -80,6 +91,17 @@ const lightMode: NymPaletteVariant = {
nav: {
background: '#FFFFFF',
},
+ mixnodes: {
+ status: {
+ active: '#1CBB67',
+ standby: '#55C1D7',
+ },
+ },
+ selectionChance: {
+ overModerate: '#20D073',
+ moderate: '#EBA53D',
+ underModerate: '#DA465B',
+ },
};
/**