Typescript: fix eslint errors and add GitHub Action for linting (#2886)

* Fix eslint errors

* GitHub Actions: add Typescript project linting

* Fix dependency

* Revert changes and exclude rule

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
This commit is contained in:
Mark Sinclair
2023-01-20 18:17:15 +00:00
committed by GitHub
parent 5376c2a4ba
commit 86e9463c42
84 changed files with 299 additions and 274 deletions
+49
View File
@@ -0,0 +1,49 @@
name: CI for linting Typescript
on:
push:
paths:
- 'ts-packages/**'
- 'sdk/typescript/**'
- nym-connect
- nym-wallet
jobs:
build:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Lint
run: yarn && yarn lint
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-ts-packages"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+3 -1
View File
@@ -1,7 +1,9 @@
{
"packages": [
"ts-packages/*",
"nym-wallet"
"nym-wallet",
"nym-connect",
"sdk/typescript/**"
],
"version": "0.0.0"
}
+2
View File
@@ -30,6 +30,8 @@
"@mui/icons-material": "^5.2.0",
"@mui/material": "^5.2.2",
"@mui/styles": "^5.2.2",
"@mui/system": ">= 5",
"@mui/lab": "^5.0.0-alpha.72",
"@nymproject/react": "^1.0.0",
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/tauri-forage": "^1.0.0-beta.2",
+1 -1
View File
@@ -1,5 +1,5 @@
import React from 'react';
import { Typography, Box } from '@mui/material';
import { Box } from '@mui/material';
import { useClientContext } from 'src/context/main';
export const AppVersion = () => {
@@ -1,13 +1,6 @@
import React from 'react';
import { ConnectionStatusKind } from '../types';
const getBusyFillColor = (color: string): string => {
if (color === '#F4B02D') {
return '#21D072';
}
return '#F4B02D';
};
const getStatusFillColor = (status: ConnectionStatusKind, hover: boolean, isError: boolean): string => {
if (isError && hover) {
return '#21D072';
@@ -57,7 +50,7 @@ export const ConnectionButton: FCWithChildren<{
busy?: boolean;
isError?: boolean;
onClick?: (status: ConnectionStatusKind) => void;
}> = ({ status, disabled, isError, onClick, busy }) => {
}> = ({ status, disabled, isError, onClick }) => {
const [hover, setHover] = React.useState<boolean>(false);
const handleClick = React.useCallback(() => {
@@ -1,5 +1,5 @@
import React from 'react';
import { Box, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
import { Box, CircularProgress, Tooltip, Typography } from '@mui/material';
import { DateTime } from 'luxon';
import { ConnectionStatusKind, GatewayPerformance } from '../types';
import { ServiceProvider } from '../types/directory';
@@ -18,6 +18,7 @@ export const Wrapper: FCWithChildren<{ disabled: boolean }> = ({ disabled, child
</Badge>
);
}
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{children}</>;
};
@@ -1,3 +1,4 @@
/* eslint-disable react/jsx-pascal-case */
import * as React from 'react';
import { ComponentMeta } from '@storybook/react';
import { NymShipyardTheme } from 'src/theme';
@@ -1,3 +1,4 @@
/* eslint-disable react/jsx-no-useless-fragment */
import React from 'react';
import LoadingButton from '@mui/lab/LoadingButton';
import {
@@ -134,7 +135,7 @@ const StatusText: FCWithChildren<{ entry: DrawEntry }> = ({ entry }) => {
export const TestAndEarnDraws: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => {
}> = () => {
const context = useTestAndEarnContext();
const draws = React.useMemo<DrawEntry[]>(
@@ -1,7 +1,7 @@
import React from 'react';
import { WalletAddressFormField } from '@nymproject/react/account/WalletAddressFormField';
import { SxProps } from '@mui/system';
import { Paper, Stack, Button, Box } from '@mui/material';
import { Box, Button, Paper, Stack } from '@mui/material';
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
import { useTestAndEarnContext } from './context/TestAndEarnContext';
@@ -10,7 +10,7 @@ export const TestAndEarnEnterWalletAddress: FCWithChildren<{
placeholder?: string;
onSubmit?: () => Promise<void> | void;
sx?: SxProps;
}> = ({ initialValue, placeholder, onSubmit, sx }) => {
}> = ({ initialValue, placeholder, onSubmit }) => {
const context = useTestAndEarnContext();
const [isAddressValid, setAddressIsValid] = React.useState(false);
return (
@@ -7,13 +7,8 @@ import { TestAndEarnPopup, TestAndEarnPopupContent } from './TestAndEarnPopup';
import { TestAndEarnContextProvider } from './context/TestAndEarnContext';
import { MockProvider } from '../../context/mocks/main';
import { ConnectionStatusKind } from '../../types';
import { TestAndEarnCurrentDraw } from './TestAndEarnCurrentDraw';
import { TestAndEarnWinner } from './TestAndEarnWinner';
import { TestAndEarnDraws } from './TestAndEarnDraws';
import { TestAndEarnWinnerWalletAddress } from './TestAndEarnWinnerWalletAddress';
import {
MockTestAndEarnProvider_NotRegistered,
MockTestAndEarnProvider_Registered,
MockTestAndEarnProvider_RegisteredAndError,
MockTestAndEarnProvider_RegisteredWithDraws,
MockTestAndEarnProvider_RegisteredWithDrawsAndEntry,
@@ -5,7 +5,7 @@ import { SxProps } from '@mui/system';
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
import { invoke } from '@tauri-apps/api';
import { useTestAndEarnContext } from './context/TestAndEarnContext';
import { ClientId, Registration } from './context/types';
import { Registration } from './context/types';
export const TestAndEarnTakePart: FCWithChildren<{
websiteLinkUrl: string;
@@ -1,3 +1,4 @@
/* eslint-disable react/jsx-pascal-case */
import * as React from 'react';
import { ComponentMeta } from '@storybook/react';
import { NymShipyardTheme } from 'src/theme';
@@ -11,7 +11,7 @@ import Content from './content/en.yaml';
export const TestAndEarnWinner: FCWithChildren<{
sx?: SxProps;
entry?: DrawEntry;
}> = ({ sx, entry }) => {
}> = ({ entry }) => {
const context = useTestAndEarnContext();
const [busy, setBusy] = React.useState(false);
const [error, setError] = React.useState<string>();
@@ -1,11 +1,11 @@
import React from 'react';
import { Box, Button, Card, CardContent, CardMedia, Typography } from '@mui/material';
import { Box } from '@mui/material';
import { SxProps } from '@mui/system';
import Content from './content/TestAndEarn/WinnerEntersWalletAddress.mdx';
export const TestAndEarnWinnerWalletAddress: FCWithChildren<{
sx?: SxProps;
}> = ({ sx }) => (
}> = () => (
<Box>
<Content />
</Box>
@@ -1,5 +1,3 @@
import { DateTime } from 'luxon';
export interface ClientId {
client_id: string;
client_id_signature: string;
@@ -1,6 +1,6 @@
import React from 'react';
import { Autocomplete, Box, Chip, Dialog, DialogProps, TextField, Typography } from '@mui/material';
import { ServiceProvider, Service, Services } from '../types/directory';
import { Autocomplete, Box, Dialog, DialogProps, TextField, Typography } from '@mui/material';
import { Service, ServiceProvider, Services } from '../types/directory';
export const ServiceProviderPopup: FCWithChildren<
DialogProps & { services: Services; onServiceProviderChanged: (sp?: ServiceProvider, s?: Service) => void }
@@ -1,6 +1,6 @@
import React, { useEffect, useMemo } from 'react';
import { Box, CircularProgress, Stack, TextField, Tooltip, Typography, MenuItem, ListItemIcon } from '@mui/material';
import { ServiceProvider, Service, Services } from '../types/directory';
import { Box, CircularProgress, MenuItem, Stack, TextField, Tooltip, Typography } from '@mui/material';
import { Service, ServiceProvider, Services } from '../types/directory';
import { useTauriEvents } from '../utils';
type ServiceWithRandomSp = {
+3 -3
View File
@@ -4,12 +4,12 @@ import { invoke } from '@tauri-apps/api';
import type { UnlistenFn } from '@tauri-apps/api/event';
import { listen } from '@tauri-apps/api/event';
import { forage } from '@tauri-apps/tauri-forage';
import { ConnectionStatusKind, GatewayPerformance } from '../types';
import { ConnectionStatsItem } from '../components/ConnectionStats';
import { ServiceProvider, Services } from '../types/directory';
import { Error } from 'src/types/error';
import { TauriEvent } from 'src/types/event';
import { getVersion } from '@tauri-apps/api/app';
import { ConnectionStatusKind, GatewayPerformance } from '../types';
import { ConnectionStatsItem } from '../components/ConnectionStats';
import { ServiceProvider, Services } from '../types/directory';
const TAURI_EVENT_STATUS_CHANGED = 'app:connection-status-changed';
+5 -4
View File
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { ConnectionStatusKind } from 'src/types';
import { ClientContext, TClientContext } from '../main';
@@ -24,6 +24,7 @@ const mockValues: TClientContext = {
export const MockProvider: FCWithChildren<{
children?: React.ReactNode;
connectionStatus?: ConnectionStatusKind;
}> = ({ connectionStatus = ConnectionStatusKind.disconnected, children }) => (
<ClientContext.Provider value={{ ...mockValues, connectionStatus }}>{children}</ClientContext.Provider>
);
}> = ({ connectionStatus = ConnectionStatusKind.disconnected, children }) => {
const value = useMemo(() => ({ ...mockValues, connectionStatus }), [connectionStatus]);
return <ClientContext.Provider value={value}>{children}</ClientContext.Provider>;
};
+1 -4
View File
@@ -8,7 +8,6 @@ import { ConnectionStatusKind } from '../types';
import { DefaultLayout } from '../layouts/DefaultLayout';
import { ConnectedLayout } from '../layouts/ConnectedLayout';
import { Services } from '../types/directory';
import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea';
export default {
title: 'App/Flow',
@@ -90,9 +89,7 @@ export const Mock: ComponentStory<typeof AppWindowFrame> = () => {
<ConnectedLayout
gatewayPerformance="Good"
showInfoModal={false}
handleCloseInfoModal={() => {
return undefined;
}}
handleCloseInfoModal={() => undefined}
status={context.connectionStatus}
busy={busy}
onConnectClick={handleConnectClick}
@@ -15,9 +15,7 @@ export const Default: ComponentStory<typeof ConnectedLayout> = () => (
<ConnectedLayout
showInfoModal={false}
gatewayPerformance="Good"
handleCloseInfoModal={() => {
return undefined;
}}
handleCloseInfoModal={() => undefined}
status={ConnectionStatusKind.connected}
connectedSince={DateTime.now()}
ipAddress="127.0.0.1"
+1
View File
@@ -2,6 +2,7 @@ import React from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CssBaseline } from '@mui/material';
import { getDesignTokens } from './theme';
// eslint-disable-next-line import/no-relative-packages
import '../../../assets/fonts/non-variable/fonts.css';
/**
+1
View File
@@ -73,6 +73,7 @@ const lightMode: NymPaletteVariant = {
* IMPORTANT: do not export this constant, always use the MUI `useTheme` hook to get the correct
* colours for dark/light mode.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const nymMixnetPalette = (variant: NymPaletteVariant): NymMixnetPalette => ({
nymMixnet: {},
});
@@ -3,18 +3,16 @@ import {
Box,
Button,
CircularProgress,
Paper,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
IconButton,
Paper,
Typography,
} from '@mui/material';
import { ArrowBackSharp } from '@mui/icons-material';
import { AccountsContext } from 'src/context';
import { useClipboard } from 'use-clipboard-copy';
import { PasswordInput, Mnemonic } from 'src/components';
import { Mnemonic, PasswordInput } from 'src/components';
import { StyledBackButton } from 'src/components/StyledBackButton';
export const MnemonicModal = () => {
@@ -7,11 +7,11 @@ import { TBondedMixnode, urls } from 'src/context';
import { NymCard } from 'src/components';
import { IdentityKey } from 'src/components/IdentityKey';
import { NodeStatus } from 'src/components/NodeStatus';
import { getIntervalAsDate } from 'src/utils';
import { Node as NodeIcon } from '../../svg-icons/node';
import { Cell, Header, NodeTable } from './NodeTable';
import { BondedMixnodeActions, TBondedMixnodeActions } from './BondedMixnodeActions';
import { NodeStats } from './NodeStats';
import { getIntervalAsDate } from 'src/utils';
const textWhenNotName = 'This node has not yet set a name';
@@ -85,8 +85,8 @@ export const BondedMixnode = ({
const getNextInterval = async () => {
try {
const { nextEpoch } = await getIntervalAsDate();
setNextEpoch(nextEpoch);
const { nextEpoch: newNextEpoch } = await getIntervalAsDate();
setNextEpoch(newNextEpoch);
} catch {
setNextEpoch(Error());
}
@@ -9,8 +9,8 @@ import { checkHasEnoughFunds, checkHasEnoughLockedTokens } from 'src/utils';
import { NodeTypeSelector, TokenPoolSelector } from 'src/components';
import { MixnodeAmount, MixnodeData } from 'src/pages/bonding/types';
import { ModalListItem } from 'src/components/Modals/ModalListItem';
import { amountSchema, mixnodeValidationSchema } from './mixnodeValidationSchema';
import { AppContext } from 'src/context';
import { amountSchema, mixnodeValidationSchema } from './mixnodeValidationSchema';
const NodeFormData = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; onNext: (data: any) => void }) => {
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
@@ -60,6 +60,7 @@ export const amountSchema = Yup.object().shape({
operatorCost: Yup.object().shape({
amount: Yup.string()
.required('An operating cost is required')
// eslint-disable-next-line
.test('valid-operating-cost', 'A valid amount is required (min 40)', async function isValidAmount(this, value) {
if (value && (!Number(value) || isLessThan(+value, 40))) {
return false;
@@ -40,6 +40,7 @@ const operatingCostAndPmValidation = {
operatorCost: Yup.object().shape({
amount: Yup.string()
.required('An operating cost is required')
// eslint-disable-next-line prefer-arrow-callback
.test('valid-operating-cost', 'A valid amount is required (min 40)', async function isValidAmount(this, value) {
if (value && (!Number(value) || isLessThan(+value, 40))) {
return false;
@@ -4,7 +4,7 @@ import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'
import { ModalListItem } from 'src/components/Modals/ModalListItem';
import { SimpleModal } from 'src/components/Modals/SimpleModal';
import { DecCoin } from '@nymproject/types';
import { TokenPoolSelector, TPoolOption } from 'src/components/TokenPoolSelector';
import { TPoolOption } from 'src/components/TokenPoolSelector';
import { ConfirmTx } from 'src/components/ConfirmTX';
import { useGetFee } from 'src/hooks/useGetFee';
import { validateAmount } from 'src/utils';
@@ -12,7 +12,7 @@ import { simulateUpdateMixnodeCostParams, simulateVestingUpdateMixnodeCostParams
import { LoadingModal } from 'src/components/Modals/LoadingModal';
import { FeeDetails } from '@nymproject/types';
//Now we are using the node setting page instead of this modal
// Now we are using the node setting page instead of this modal
export const NodeSettings = ({
currentPm,
isVesting,
@@ -108,7 +108,7 @@ export const NodeSettings = ({
okLabel="Next"
onClose={onClose}
>
<Tabs tabs={['System variables']} selectedTab={'System variables'} disableActiveTabHighlight />
<Tabs tabs={['System variables']} selectedTab="System variables" disableActiveTabHighlight />
<Box sx={{ p: 3 }}>
<Typography fontWeight={600} sx={{ mb: 1 }}>
Set profit margin
@@ -1,6 +1,6 @@
import * as React from 'react';
import { useEffect } from 'react';
import { Typography } from '@mui/material';
import { useEffect, useState } from 'react';
import { TBondedGateway, TBondedMixnode } from 'src/context';
import { useGetFee } from 'src/hooks/useGetFee';
import { isGateway, isMixnode } from 'src/types';
+4 -3
View File
@@ -2,10 +2,10 @@ import React, { useContext, useState } from 'react';
import { Button, Stack, Typography, Grid, useMediaQuery, useTheme } from '@mui/material';
import { Tune as TuneIcon, BorderColor as BorderColorIcon } from '@mui/icons-material';
import { CoinMark } from '@nymproject/react/coins/CoinMark';
import { NymCard, ClientAddress } from '../../components';
import { SignMessageModal } from './SignMessageModal';
import { PoweredByBity } from 'src/svg-icons';
import { AppContext } from 'src/context';
import { NymCard, ClientAddress } from '..';
import { SignMessageModal } from './SignMessageModal';
// TODO retrieve this value from env
const EXCHANGE_URL = 'https://buy.nymtech.net';
@@ -114,7 +114,8 @@ export const Tutorial = () => {
icon={<CoinMark width={20} height={20} />}
text={
<Typography fontSize={14} lineHeight="24px" sx={{ color: (t) => t.palette.nym.text.muted }}>
{`Send the defined BTC amount to Bity's address that's given to you. As soon as your BTC tx has 4 confirmations, Bity will send the purchased NYM tokens to your wallet.`}
{`Send the defined BTC amount to Bity's address that's given to you. As soon as your BTC tx has 4
confirmations, Bity will send the purchased NYM tokens to your wallet.`}
</Typography>
}
/>
@@ -6,11 +6,13 @@ import { splice } from '../utils';
const AddressTooltip: FCWithChildren<{ visible?: boolean; address?: string }> = ({ visible, address, children }) => {
if (!visible || !address) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{children}</>;
}
return (
<Tooltip title={address} arrow>
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
<>{children}</>
</Tooltip>
);
@@ -1,6 +1,5 @@
import React, { useState } from 'react';
import { Box, Button, Stack, Tooltip, Typography } from '@mui/material';
import { DelegationEventKind } from '@nymproject/types';
import { Delegate, Undelegate } from '../../svg-icons';
import { ActionsMenu, ActionsMenuItem } from '../ActionsMenu';
import { DelegateListItemPending } from './types';
@@ -12,6 +12,7 @@ const getStakeSaturation = (item: DelegationWithEverything) =>
!item.stake_saturation ? '-' : `${decimalToPercentage(item.stake_saturation)}%`;
const getRewardValue = (item: DelegationWithEverything) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { unclaimed_rewards } = item;
return !unclaimed_rewards ? '-' : `${unclaimed_rewards.amount} ${unclaimed_rewards.denom}`;
};
@@ -32,11 +33,11 @@ export const DelegationItem = ({
const tooltipText = () => {
if (nodeIsUnbonded) {
return 'This node has unbonded and it does not exist anymore. You need to undelegate from it to get your stake and outstanding rewards (if any) back.';
} else if (item.uses_vesting_contract_tokens) {
return 'Delegation made with locked tockens';
} else {
return '';
}
if (item.uses_vesting_contract_tokens) {
return 'Delegation made with locked tockens';
}
return '';
};
return (
@@ -1,5 +1,4 @@
import { Box, SxProps } from '@mui/material';
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
import React, { useEffect } from 'react';
import { FeeDetails } from '@nymproject/types';
import { useGetFee } from 'src/hooks/useGetFee';
@@ -42,6 +42,7 @@ export const LogViewer: FC = () => {
useEffect(() => {
listen('log://log', (event) => {
// eslint-disable-next-line no-console
console.log(event.payload);
const payload = event.payload as RecordPayload;
messages.current.unshift(payload);
@@ -27,11 +27,9 @@ export const ModalFee = ({ fee, isLoading, error, divider }: TFeeProps) => (
</>
);
export const ModalTotalAmount = ({ fee, amount, isLoading, error, divider }: TTotalAmountProps) => {
return (
<>
<ModalListItem label="Total amount" value={getValue({ fee, amount, isLoading, error })} fontWeight={600} />
{divider && <ModalDivider />}
</>
);
};
export const ModalTotalAmount = ({ fee, amount, isLoading, error, divider }: TTotalAmountProps) => (
<>
<ModalListItem label="Total amount" value={getValue({ fee, amount, isLoading, error })} fontWeight={600} />
{divider && <ModalDivider />}
</>
);
@@ -24,7 +24,7 @@ export const NodeDetails = ({ saturation }: { saturation?: string }) => {
<Divider sx={{ my: 1 }} />
<Stack direction="row" justifyContent="space-between">
<Typography fontWeight="medium">Selection probability</Typography>
<InclusionProbability probability={computeSelectionProbability(parseInt(saturation))} />
<InclusionProbability probability={computeSelectionProbability(parseInt(saturation, 10))} />
</Stack>
</CardContent>
</Card>
@@ -1,9 +1,9 @@
import React, { useContext } from 'react';
import { Stack, Typography, SxProps } from '@mui/material';
import { Link } from '@nymproject/react/link/Link';
import { AppContext } from 'src/context';
import { TTransactionDetails } from './types';
import { ConfirmationModal } from '../Modals/ConfirmationModal';
import { AppContext } from 'src/context';
export const SendSuccessModal = ({
txDetails,
+1
View File
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {
FeeDetails,
DecCoin,
+4 -4
View File
@@ -1,12 +1,12 @@
import React, { createContext, FC, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { getDelegationSummary, undelegateAllFromMixnode, undelegateFromMixnode } from 'src/requests/delegation';
import { getDelegationSummary, undelegateFromMixnode } from 'src/requests/delegation';
import {
DelegationWithEverything,
FeeDetails,
DecCoin,
DelegationWithEverything,
Fee,
FeeDetails,
TransactionExecuteResult,
WrappedDelegationEvent,
Fee,
} from '@nymproject/types';
import type { Network } from 'src/types';
import {
+1 -1
View File
@@ -2,7 +2,7 @@ import React, { createContext, useEffect, useMemo, useState } from 'react';
import { forage } from '@tauri-apps/tauri-forage';
import { useNavigate } from 'react-router-dom';
import { useSnackbar } from 'notistack';
import { Account, AccountEntry, MixNodeBond, MixNodeDetails } from '@nymproject/types';
import { Account, AccountEntry, MixNodeDetails } from '@nymproject/types';
import { getVersion } from '@tauri-apps/api/app';
import { AppEnv, Network } from '../types';
import { TUseuserBalance, useGetBalance } from '../hooks/useGetBalance';
+2 -2
View File
@@ -1,7 +1,7 @@
import { FeeDetails, DecCoin, TransactionExecuteResult } from '@nymproject/types';
import { FeeDetails, TransactionExecuteResult } from '@nymproject/types';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import type { Network } from 'src/types';
import { TBondedGateway, TBondedMixnode, BondingContext } from '../bonding';
import { BondingContext, TBondedGateway, TBondedMixnode } from '../bonding';
import { mockSleep } from './utils';
const SLEEP_MS = 1000;
+17 -18
View File
@@ -1,11 +1,11 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
DelegationWithEverything,
DecCoin,
TransactionExecuteResult,
FeeDetails,
Fee,
CurrencyDenom,
DecCoin,
DelegationWithEverything,
Fee,
FeeDetails,
TransactionExecuteResult,
} from '@nymproject/types';
import { DelegationContext, TDelegationTransaction } from '../delegations';
@@ -190,18 +190,17 @@ export const MockDelegationContextProvider: FCWithChildren = ({ children }) => {
};
};
const undelegateVesting = async (mix_id: number, _fee?: FeeDetails) => {
return {
logs_json: '',
data_json: '',
transaction_hash: '',
gas_info: {
gas_wanted: { gas_units: BigInt(1) },
gas_used: { gas_units: BigInt(1) },
},
fee: { amount: '1', denom: 'nym' as CurrencyDenom },
};
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const undelegateVesting = async (mix_id: number, _fee?: FeeDetails) => ({
logs_json: '',
data_json: '',
transaction_hash: '',
gas_info: {
gas_wanted: { gas_units: BigInt(1) },
gas_used: { gas_units: BigInt(1) },
},
fee: { amount: '1', denom: 'nym' as CurrencyDenom },
});
const resetState = () => {
setIsLoading(true);
+1 -1
View File
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react';
import React, { useMemo } from 'react';
import type { TAppContext } from '../main';
import { AppContext } from '../main';
+1 -1
View File
@@ -1,4 +1,4 @@
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { DelegationWithEverything, TransactionExecuteResult } from '@nymproject/types';
import { RewardsContext, TRewardsTransaction } from '../rewards';
import { useDelegationContext } from '../delegations';
+1 -1
View File
@@ -1,4 +1,4 @@
import React, { createContext, FC, useContext, useEffect, useMemo, useState } from 'react';
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { FeeDetails, TransactionExecuteResult } from '@nymproject/types';
import { useDelegationContext } from './delegations';
import { claimDelegatorRewards } from '../requests';
+1 -1
View File
@@ -1,4 +1,4 @@
import React, { useContext, useEffect, useState } from 'react';
import React, { useContext, useState } from 'react';
import { Box } from '@mui/material';
import { AppContext } from '../../context/main';
+1 -2
View File
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { Refresh } from '@mui/icons-material';
import {
Box,
@@ -14,7 +14,6 @@ import {
Typography,
} from '@mui/material';
import { useSnackbar } from 'notistack';
import { useContext, useEffect, useState } from 'react';
import { NymCard } from 'src/components';
import { AppContext } from 'src/context/main';
import { Period } from 'src/types';
+8 -6
View File
@@ -99,8 +99,8 @@ const Bonding = () => {
(await getMixnodeStakeSaturation(newMixId)).uncapped_saturation,
);
if (newSaturation && newSaturation > 1) {
const saturationPercentage = Math.round(newSaturation * 100);
return { isOverSaturated: true, saturationPercentage };
const newSaturationPercentage = Math.round(newSaturation * 100);
return { isOverSaturated: true, saturationPercentage: newSaturationPercentage };
}
return { isOverSaturated: false, saturationPercentage: undefined };
} catch (e) {
@@ -113,10 +113,12 @@ const Bonding = () => {
switch (action) {
case 'bondMore': {
if (bondedNode && isMixnode(bondedNode)) {
const { isOverSaturated, saturationPercentage } = await handleCheckStakeSaturation(bondedNode.mixId);
if (isOverSaturated && saturationPercentage) {
const { isOverSaturated, saturationPercentage: newSaturationPercentage } = await handleCheckStakeSaturation(
bondedNode.mixId,
);
if (isOverSaturated && newSaturationPercentage) {
setShowModal('bond-more-oversaturated');
setSaturationPercentage(saturationPercentage.toString());
setSaturationPercentage(newSaturationPercentage.toString());
break;
}
}
@@ -178,7 +180,7 @@ const Bonding = () => {
{showModal === 'bond-more-oversaturated' && saturationPercentage && (
<BondOversaturatedModal
open={true}
open
onClose={() => setShowModal(undefined)}
onContinue={() => setShowModal('bond-more')}
saturationPercentage={saturationPercentage}
@@ -13,12 +13,12 @@ import { Tabs } from 'src/components/Tabs';
import { useBondingContext, BondingContextProvider, TBondedMixnode } from 'src/context';
import { AppContext, urls } from 'src/context/main';
import { isMixnode } from 'src/types';
import { getIntervalAsDate } from 'src/utils';
import { NodeGeneralSettings } from './settings-pages/general-settings';
import { NodeUnbondPage } from './settings-pages/NodeUnbondPage';
import { createNavItems } from './node-settings.constant';
import { isMixnode } from 'src/types';
import { ApyPlayground } from './apy-playground';
import { getIntervalAsDate } from 'src/utils';
export const NodeSettings = () => {
const theme = useTheme();
@@ -1,14 +1,13 @@
import React, { useState, useEffect, useContext } from 'react';
import React, { useEffect, useState } from 'react';
import { Box, Card, CardContent, CardHeader, Grid, Typography } from '@mui/material';
import { decimalToPercentage, percentToDecimal } from '@nymproject/types';
import { ResultsTable } from 'src/components/RewardsPlayground/ResultsTable';
import { getDelegationSummary } from 'src/requests';
import { NodeDetails } from 'src/components/RewardsPlayground/NodeDetail';
import { Inputs, CalculateArgs } from 'src/components/RewardsPlayground/Inputs';
import { AppContext, TBondedMixnode } from 'src/context';
import { computeEstimate, computeStakeSaturation, handleCalculatePeriodRewards } from './utils';
import { CalculateArgs, Inputs } from 'src/components/RewardsPlayground/Inputs';
import { TBondedMixnode } from 'src/context';
import { useSnackbar } from 'notistack';
import { LoadingModal } from 'src/components/Modals/LoadingModal';
import { computeEstimate, computeStakeSaturation, handleCalculatePeriodRewards } from './utils';
export type DefaultInputValues = {
profitMargin: string;
@@ -76,11 +75,12 @@ export const ApyPlayground = ({ bondedNode }: { bondedNode: TBondedMixnode }) =>
const handleCalculateEstimate = async ({ bond, delegations, uptime, profitMargin, operatorCost }: CalculateArgs) => {
try {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { estimation, reward_params } = await computeEstimate({
mixId: bondedNode.mixId,
uptime: uptime,
profitMargin: profitMargin,
operatorCost: operatorCost,
uptime,
profitMargin,
operatorCost,
totalDelegation: delegations,
pledgeAmount: bond,
});
@@ -24,7 +24,7 @@ export const computeEstimate = async ({
operatorCost: string;
}) => {
const computedEstimate = await computeMixnodeRewardEstimation({
mixId: mixId,
mixId,
performance: percentToDecimal(uptime),
pledgeAmount: Math.round(+pledgeAmount * SCALE_FACTOR),
totalDelegation: Math.round(+totalDelegation * SCALE_FACTOR),
@@ -4,6 +4,7 @@ import { TBondedMixnode, TBondedGateway } from 'src/context/bonding';
import { Error } from 'src/components/Error';
import { UnbondModal } from 'src/components/Bonding/modals/UnbondModal';
import { isMixnode } from 'src/types';
interface Props {
bondedNode: TBondedMixnode | TBondedGateway;
@@ -13,7 +14,7 @@ interface Props {
export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => {
const [confirmField, setConfirmField] = useState('');
const [isConfirmed, setIsConfirmed] = useState(false);
//TODO: Check what happens with a gateway
// TODO: Check what happens with a gateway
return (
<Box sx={{ p: 3, minHeight: '450px' }}>
<Grid container justifyContent="space-between">
@@ -1,11 +1,11 @@
import { useState } from 'react';
import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Button, Divider, Typography, TextField, Grid, CircularProgress, Box } from '@mui/material';
import { Box, Button, Divider, Grid, TextField, Typography } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { isMixnode } from 'src/types';
import { simulateUpdateMixnodeConfig, simulateVestingUpdateMixnodeConfig, updateMixnodeConfig } from 'src/requests';
import { TBondedMixnode, TBondedGateway } from 'src/context/bonding';
import { TBondedGateway, TBondedMixnode } 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';
@@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { Button, Divider, Typography, TextField, InputAdornment, Grid, Box, FormHelperText } from '@mui/material';
import { Box, Button, Divider, FormHelperText, Grid, InputAdornment, TextField, Typography } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types';
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
@@ -88,7 +88,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 = {
const mixNodeCostParams = {
profit_margin_percent: (+data.profitMargin / 100).toString(),
interval_operating_cost: {
amount: data.operatorCost.amount,
@@ -97,9 +97,9 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
};
try {
if (bondedNode.proxy) {
await vestingUpdateMixnodeCostParams(MixNodeCostParams);
await vestingUpdateMixnodeCostParams(mixNodeCostParams);
} else {
await updateMixnodeCostParams(MixNodeCostParams);
await updateMixnodeCostParams(mixNodeCostParams);
}
await getPendingEvents();
reset();
@@ -132,13 +132,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode
/>
)}
{isSubmitting && <LoadingModal />}
<Alert
title={
<>
<Box component="span" sx={{ fontWeight: 600 }}>{`Next interval: ${intervalTime}`}</Box>
</>
}
/>
<Alert title={<Box component="span" sx={{ fontWeight: 600 }}>{`Next interval: ${intervalTime}`}</Box>} />
<Grid container direction="column">
<Grid item container alignItems="left" justifyContent="space-between" padding={3} spacing={1}>
<Grid item xl={6}>
@@ -1,15 +1,15 @@
import React, { useState } from 'react';
import { Box, Button, Divider, Grid } from '@mui/material';
import { isMixnode } from 'src/types';
import { TBondedMixnode, TBondedGateway } from '../../../../../context/bonding';
import { InfoSettings } from './InfoSettings';
import { ParametersSettings } from './ParametersSettings';
import { isMixnode } from 'src/types';
const nodeGeneralNav = ['Info', 'Parameters'];
export const NodeGeneralSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBondedGateway }) => {
const [settingsCard, setSettingsCard] = useState<string>(nodeGeneralNav[0]);
//TODO: Check what happens with a gateway
// TODO: Check what happens with a gateway
return (
<Box sx={{ pl: 3, pt: 3 }}>
<Grid container direction="row" spacing={3}>
+6 -6
View File
@@ -1,6 +1,6 @@
import React, { FC, useContext, useEffect, useState } from 'react';
import { Box, Button, Paper, Stack, Typography, CircularProgress } from '@mui/material';
import { useTheme, Theme } from '@mui/material/styles';
import { Box, Button, CircularProgress, Paper, Stack, Typography } from '@mui/material';
import { Theme, useTheme } from '@mui/material/styles';
import { DecCoin, decimalToFloatApproximation, DelegationWithEverything, FeeDetails } from '@nymproject/types';
import { Link } from '@nymproject/react/link/Link';
import { AppContext, urls } from 'src/context/main';
@@ -9,8 +9,9 @@ import { TPoolOption } from 'src/components';
import { Console } from 'src/utils/console';
import { OverSaturatedBlockerModal } from 'src/components/Delegation/DelegateBlocker';
import { getSpendableCoins, userBalance } from 'src/requests';
import { getIntervalAsDate, toPercentIntegerString } from 'src/utils';
import { RewardsSummary } from '../../components/Rewards/RewardsSummary';
import { DelegationContextProvider, useDelegationContext, TDelegations } from '../../context/delegations';
import { DelegationContextProvider, TDelegations, useDelegationContext } from '../../context/delegations';
import { RewardsContextProvider, useRewardsContext } from '../../context/rewards';
import { DelegateModal } from '../../components/Delegation/DelegateModal';
import { UndelegateModal } from '../../components/Delegation/UndelegateModal';
@@ -18,7 +19,6 @@ import { DelegationListItemActions } from '../../components/Delegation/Delegatio
import { RedeemModal } from '../../components/Rewards/RedeemModal';
import { DelegationModal, DelegationModalProps } from '../../components/Delegation/DelegationModal';
import { backDropStyles, modalStyles } from '../../../.storybook/storiesStyles';
import { toPercentIntegerString, getIntervalAsDate } from 'src/utils';
const storybookStyles = (theme: Theme, isStorybook?: boolean, backdropProps?: object) =>
isStorybook
@@ -77,8 +77,8 @@ export const Delegation: FC<{ isStorybook?: boolean }> = ({ isStorybook }) => {
const getNextInterval = async () => {
try {
const { nextEpoch } = await getIntervalAsDate();
setNextEpoch(nextEpoch);
const { nextEpoch: newNextEpoch } = await getIntervalAsDate();
setNextEpoch(newNextEpoch);
} catch {
setNextEpoch(Error());
}
+1 -2
View File
@@ -33,5 +33,4 @@ export const unbond = async (type: EnumNodeType) => {
return unbondGateway();
};
export const bondMore = async (args: TBondMoreArgs) =>
invokeWrapper<TransactionExecuteResult>('pledge_more', args);
export const bondMore = async (args: TBondMoreArgs) => invokeWrapper<TransactionExecuteResult>('pledge_more', args);
+6 -7
View File
@@ -1,14 +1,13 @@
import {
StakeSaturationResponse,
MixnodeStatusResponse,
InclusionProbabilityResponse,
DecCoin,
MixNodeDetails,
GatewayBond,
RewardEstimationResponse,
WrappedDelegationEvent,
InclusionProbabilityResponse,
MixNodeDetails,
MixnodeStatusResponse,
PendingIntervalEvent,
Coin,
RewardEstimationResponse,
StakeSaturationResponse,
WrappedDelegationEvent,
} from '@nymproject/types';
import { Interval, TGatewayReport, TNodeDescription } from 'src/types';
import { invokeWrapper } from './wrapper';
+1 -2
View File
@@ -64,8 +64,7 @@ export const simulateClaimOperatorReward = async () => invokeWrapper<FeeDetails>
export const simulateVestingClaimOperatorReward = async () =>
invokeWrapper<FeeDetails>('simulate_vesting_claim_operator_reward');
export const simulateBondMore = async (args: any) =>
invokeWrapper<FeeDetails>('simulate_pledge_more', args);
export const simulateBondMore = async (args: any) => invokeWrapper<FeeDetails>('simulate_pledge_more', args);
export const simulateVestingBondMore = async (args: any) =>
invokeWrapper<FeeDetails>('simulate_vesting_pledge_more', args);
+5 -10
View File
@@ -106,13 +106,8 @@ export const vestingClaimOperatorReward = async (fee?: Fee) =>
export const vestingClaimDelegatorRewards = async (mixId: number) =>
invokeWrapper<TransactionExecuteResult>('vesting_claim_delegator_reward', { mixId });
export const vestingBondMore = async ({
fee,
additionalPledge,
}: {
fee?: Fee;
additionalPledge: DecCoin;
}) => invokeWrapper<TransactionExecuteResult>('vesting_pledge_more', {
fee,
additionalPledge,
});
export const vestingBondMore = async ({ fee, additionalPledge }: { fee?: Fee; additionalPledge: DecCoin }) =>
invokeWrapper<TransactionExecuteResult>('vesting_pledge_more', {
fee,
additionalPledge,
});
File diff suppressed because one or more lines are too long
+1 -10
View File
@@ -1,12 +1,4 @@
import {
Gateway,
DecCoin,
MixNode,
PledgeData,
MixNodeCostParams,
PendingIntervalEventData,
PendingEpochEventData,
} from '@nymproject/types';
import { DecCoin, Gateway, MixNode, MixNodeCostParams, PledgeData } from '@nymproject/types';
import { Fee } from '@nymproject/types/dist/types/rust/Fee';
import { TBondedGateway, TBondedMixnode } from 'src/context';
@@ -52,7 +44,6 @@ export type TBondMixNodeArgs = {
export type TBondMoreArgs = {
additionalPledge: DecCoin;
fee?: Fee;
};
export type TNodeDescription = {
+6 -1
View File
@@ -1,3 +1,8 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface Epoch { id: number, start: bigint, end: bigint, duration_seconds: bigint, }
export interface Epoch {
id: number;
start: bigint;
end: bigint;
duration_seconds: bigint;
}
+1 -1
View File
@@ -1,4 +1,4 @@
import type { DecCoin } from '../../../../ts-packages/types/src/types/rust/DecCoin';
import type { DecCoin } from '@nymproject/types';
export interface TauriContractStateParams {
minimum_mixnode_pledge: DecCoin;
+1 -3
View File
@@ -3,7 +3,7 @@ import bs58 from 'bs58';
import Big from 'big.js';
import { valid } from 'semver';
import { add, format, fromUnixTime } from 'date-fns';
import { isValidRawCoin, DecCoin, MixNodeCostParams } from '@nymproject/types';
import { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types';
import { TPoolOption } from 'src/components';
import {
getCurrentInterval,
@@ -14,8 +14,6 @@ import {
} from '../requests';
import { Console } from './console';
export * from './nextEpoch';
export const validateKey = (key: string, bytesLength: number): boolean => {
// it must be a valid base58 key
try {
-23
View File
@@ -1,23 +0,0 @@
import { getCurrentInterval } from 'src/requests';
import { add, format, fromUnixTime } from 'date-fns';
export const getIntervalAsDate = async () => {
const interval = await getCurrentInterval();
const secondsToNextInterval =
Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds);
const intervalTime = format(
add(new Date(), {
seconds: secondsToNextInterval,
}),
'dd/MM/yyyy, HH:mm',
);
const nextEpoch = format(
add(fromUnixTime(Number(interval.current_epoch_start_unix)), {
seconds: Number(interval.epoch_length_seconds),
}),
'HH:mm',
);
return { intervalTime, nextEpoch };
};
@@ -69,7 +69,8 @@ export const Content: FCWithChildren = () => {
};
const log = React.useRef<Log[]>([]);
const [_logTrigger, setLogTrigger] = React.useState(Date.now());
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [logTrigger, setLogTrigger] = React.useState(Date.now());
const [uploadState, setUploadState] = React.useState<UploadState>({
dialogOpen: false,
@@ -1,3 +1,4 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { Debug } from '@nymproject/nym-client-wasm';
/**
@@ -11,8 +11,10 @@ import * as Comlink from 'comlink';
// Doing it this way, saves having to support a large variety of bundlers and their quirks.
//
// @ts-ignore
// eslint-disable-next-line import/no-extraneous-dependencies
import wasmBytes from '@nymproject/nym-client-wasm/nym_client_wasm_bg.wasm';
// eslint-disable-next-line import/no-extraneous-dependencies
import init, {
NymClient,
NymClientBuilder,
@@ -46,6 +48,7 @@ console.log('[Nym WASM client] Starting Nym WASM web worker...');
* Helper method to send typed messages.
* @param event The strongly typed message to send back to the calling thread.
*/
// eslint-disable-next-line no-restricted-globals
const postMessageWithType = <E>(event: E) => self.postMessage(event);
/**
@@ -1,7 +1,8 @@
import { Color, PaletteMode } from '@mui/material';
import { PaletteMode } from '@mui/material';
import { createTheme, ThemeOptions } from '@mui/material/styles';
import { darkMode, nymPalette, NymPaletteVariant } from './common';
import { createDarkModePalette, createLightModePalette } from './theme';
// eslint-disable-next-line import/no-cycle
import { createDarkModePalette, createLightModePalette } from './utils';
/**
* A palette definition only for the Network Explorer that extends the Nym palette
@@ -53,7 +54,7 @@ export interface NetworkExplorerPalette {
backgroud: string;
color: string;
border: string;
}
};
};
}
@@ -111,7 +112,7 @@ export const networkExplorerPalette = (variant: NymPaletteVariant): NetworkExplo
backgroud: variant.mode === 'light' ? '#FAFAFA' : '#C7C9CD',
color: variant.mode === 'light' ? '#7D7D7D' : '#636466',
border: variant.mode === 'light' ? '#DFDEDE' : '#DDDDDD',
}
},
},
});
+8 -28
View File
@@ -1,8 +1,12 @@
import { createTheme, Palette, PaletteOptions, ThemeOptions } from '@mui/material/styles';
import { createTheme, Palette, ThemeOptions } from '@mui/material/styles';
import { PaletteMode } from '@mui/material';
import { darkMode, lightMode, nymPalette, NymPalette, variantToMUIPalette } from './common';
import { NymWalletPalette, nymWalletPallete } from './wallet';
import { networkExplorerPalette, NetworkExplorerPalette } from './network-explorer';
import { nymPalette, NymPalette } from './common';
// eslint-disable-next-line import/no-cycle
import { NymWalletPalette } from './wallet';
// eslint-disable-next-line import/no-cycle
import { NetworkExplorerPalette } from './network-explorer';
// eslint-disable-next-line import/no-cycle
import { createDarkModePalette, createLightModePalette } from './utils';
/**
* To use the theme, copy the file in `../../template/mui-theme.d.ts` into `src/typings/mui-theme.d.ts` in your project.
@@ -30,30 +34,6 @@ export interface NymTheme {
*/
export type NymPaletteWithExtensionsOptions = Partial<NymPaletteWithExtensions>;
/**
* Returns the Nym palette for light mode.
*/
export const createLightModePalette = (): PaletteOptions & NymPaletteWithExtensionsOptions => ({
nym: {
...nymPalette,
...nymWalletPallete(lightMode),
...networkExplorerPalette(lightMode),
},
...variantToMUIPalette(lightMode),
});
/**
* Returns the Nym palette for dark mode.
*/
export const createDarkModePalette = (): PaletteOptions & NymPaletteWithExtensionsOptions => ({
nym: {
...nymPalette,
...nymWalletPallete(darkMode),
...networkExplorerPalette(darkMode),
},
...variantToMUIPalette(darkMode),
});
/**
* Gets the theme options to be passed to `createTheme`.
*
+31
View File
@@ -0,0 +1,31 @@
import { PaletteOptions } from '@mui/material/styles';
import { darkMode, lightMode, nymPalette, variantToMUIPalette } from './common';
import { nymWalletPallete } from './wallet';
// eslint-disable-next-line import/no-cycle
import { networkExplorerPalette } from './network-explorer';
// eslint-disable-next-line import/no-cycle
import { NymPaletteWithExtensionsOptions } from './theme';
/**
* Returns the Nym palette for light mode.
*/
export const createLightModePalette = (): PaletteOptions & NymPaletteWithExtensionsOptions => ({
nym: {
...nymPalette,
...nymWalletPallete(lightMode),
...networkExplorerPalette(lightMode),
},
...variantToMUIPalette(lightMode),
});
/**
* Returns the Nym palette for dark mode.
*/
export const createDarkModePalette = (): PaletteOptions & NymPaletteWithExtensionsOptions => ({
nym: {
...nymPalette,
...nymWalletPallete(darkMode),
...networkExplorerPalette(darkMode),
},
...variantToMUIPalette(darkMode),
});
@@ -1,3 +1,4 @@
import * as React from 'react';
import { Box, Collapse, Alert, IconButton, Typography, Divider } from '@mui/material';
import CloseIcon from '@mui/icons-material/Close';
import { SxProps } from '@mui/system';
@@ -1,7 +1,6 @@
import * as React from 'react';
import { ComponentMeta } from '@storybook/react';
import { Stack, Typography } from '@mui/material';
import { CoinMark } from './CoinMark';
import { CoinMarkTestnet } from './CoinMarkTestnet';
export default {
@@ -1,6 +1,6 @@
import * as React from 'react';
import type { DecCoin } from '@nymproject/types';
import { Stack, SxProps, Typography } from '@mui/material';
import { Stack, SxProps } from '@mui/material';
import { CurrencyWithCoinMark } from './CurrencyWithCoinMark';
import { CURRENCY_AMOUNT_SPACING, CurrencyAmount } from './CurrencyAmount';
@@ -9,16 +9,14 @@ export default {
export const Default = () => <Tooltip title="tooltip" id="field-name" placement="top-start" arrow />;
export const NEStyle = () => {
return (
<Tooltip
title="Level of stake saturation for this node. Nodes receive more rewards the higher their saturation level, up to 100%. Beyond 100% no additional rewards are granted. The current stake saturation level is: 1 million NYM, computed as S/K where S is total amount of tokens available to stakeholders and K is the number of nodes in the reward set."
id="field-name"
placement="top-start"
textColor="#111826"
bgColor="#A0AED1"
maxWidth={230}
arrow
/>
);
};
export const NEStyle = () => (
<Tooltip
title="Level of stake saturation for this node. Nodes receive more rewards the higher their saturation level, up to 100%. Beyond 100% no additional rewards are granted. The current stake saturation level is: 1 million NYM, computed as S/K where S is total amount of tokens available to stakeholders and K is the number of nodes in the reward set."
id="field-name"
placement="top-start"
textColor="#111826"
bgColor="#A0AED1"
maxWidth={230}
arrow
/>
);
@@ -1,12 +1,24 @@
import * as React from 'react';
import { Tooltip as MUITooltip, TooltipProps, IconButton } from '@mui/material';
import { IconButton, Tooltip as MUITooltip } from '@mui/material';
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
export interface CustomTooltipProps {
title: string;
arrow?: boolean;
id: string;
placement?: "bottom" | "left" | "right" | "top" | "bottom-end" | "bottom-start" | "left-end" | "left-start" | "right-end" | "right-start" | "top-end" | "top-start";
placement?:
| 'bottom'
| 'left'
| 'right'
| 'top'
| 'bottom-end'
| 'bottom-start'
| 'left-end'
| 'left-start'
| 'right-end'
| 'right-start'
| 'top-end'
| 'top-start';
textColor?: string;
bgColor?: string;
maxWidth?: number;
@@ -42,7 +54,7 @@ export const Tooltip = (props: CustomTooltipProps) => {
componentsProps={{
tooltip: {
sx: {
maxWidth: maxWidth,
maxWidth,
background: bgColor,
color: textColor,
'& .MuiTooltip-arrow': {
@@ -1,7 +1,7 @@
import type {PendingEpochEventData} from "./PendingEpochEventData";
import type { PendingEpochEventData } from './PendingEpochEventData';
export interface PendingEpochEvent {
id: number,
created_at: bigint,
event: PendingEpochEventData,
id: number;
created_at: bigint;
event: PendingEpochEventData;
}
@@ -1,7 +1,7 @@
import type {PendingIntervalEventData} from "./PendingIntervalEventData";
import type { PendingIntervalEventData } from './PendingIntervalEventData';
export interface PendingIntervalEvent {
id: number,
created_at: bigint,
event: PendingIntervalEventData,
id: number;
created_at: bigint;
event: PendingIntervalEventData;
}
+7 -10
View File
@@ -61,17 +61,14 @@ module.exports = (baseDir, htmlPath) => ({
plugins: [
// new CleanWebpackPlugin(),
... Array.isArray(htmlPath)
? htmlPath.map(
(item) =>
new HtmlWebpackPlugin(item),
)
...(Array.isArray(htmlPath)
? htmlPath.map((item) => new HtmlWebpackPlugin(item))
: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(baseDir, htmlPath || 'src/index.html'),
})
],
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(baseDir, htmlPath || 'src/index.html'),
}),
]),
new ForkTsCheckerWebpackPlugin({
typescript: {