prettier updates
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import React from "react";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { CircularProgress } from "@material-ui/core";
|
||||
import { Alert, AlertTitle } from "@material-ui/lab";
|
||||
import React from 'react'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
import { CircularProgress } from '@material-ui/core'
|
||||
import { Alert, AlertTitle } from '@material-ui/lab'
|
||||
|
||||
type ConfirmationProps = {
|
||||
isLoading: boolean;
|
||||
progressMessage: string;
|
||||
successMessage: string;
|
||||
failureMessage: string;
|
||||
error: Error;
|
||||
};
|
||||
isLoading: boolean
|
||||
progressMessage: string
|
||||
successMessage: string
|
||||
failureMessage: string
|
||||
error: Error
|
||||
}
|
||||
|
||||
export default function Confirmation({
|
||||
isLoading,
|
||||
@@ -19,29 +19,25 @@ export default function Confirmation({
|
||||
failureMessage,
|
||||
error,
|
||||
}: ConfirmationProps) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{isLoading ? (
|
||||
<React.Fragment>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
{progressMessage}
|
||||
</Typography>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CircularProgress />
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
return isLoading ? (
|
||||
<>
|
||||
<Typography variant='h6' gutterBottom>
|
||||
{progressMessage}
|
||||
</Typography>
|
||||
<Grid item xs={12} sm={6}>
|
||||
<CircularProgress />
|
||||
</Grid>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{error === null ? (
|
||||
<Alert severity='success'>{successMessage}</Alert>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
{error === null ? (
|
||||
<Alert severity="success">{successMessage}</Alert>
|
||||
) : (
|
||||
<Alert severity="error">
|
||||
<AlertTitle>{error.name}</AlertTitle>
|
||||
<strong>{failureMessage}</strong> - {error.message}
|
||||
</Alert>
|
||||
)}
|
||||
</React.Fragment>
|
||||
<Alert severity='error'>
|
||||
<AlertTitle>{error.name}</AlertTitle>
|
||||
<strong>{failureMessage}</strong> - {error.message}
|
||||
</Alert>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
import React, { useEffect, useState, ChangeEvent } from "react";
|
||||
import { printableBalanceToNative } from "@nymproject/nym-validator-client/dist/currency";
|
||||
import { Coin, nativeToPrintable } from "@nymproject/nym-validator-client";
|
||||
import { Alert } from "@material-ui/lab";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import React, { useEffect, useState, ChangeEvent } from 'react'
|
||||
import { printableBalanceToNative } from '@nymproject/nym-validator-client/dist/currency'
|
||||
import { Coin, nativeToPrintable } from '@nymproject/nym-validator-client'
|
||||
import { Alert } from '@material-ui/lab'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
InputAdornment,
|
||||
} from "@material-ui/core";
|
||||
import bs58 from "bs58";
|
||||
import semver from "semver";
|
||||
import { NodeType } from "../../common/node";
|
||||
import { theme } from "../../lib/theme";
|
||||
} from '@material-ui/core'
|
||||
import bs58 from 'bs58'
|
||||
import semver from 'semver'
|
||||
import { NodeType } from '../../common/node'
|
||||
import { theme } from '../../lib/theme'
|
||||
import {
|
||||
basicRawCoinValueValidation,
|
||||
makeBasicStyle,
|
||||
validateRawPort,
|
||||
} from "../../common/helpers";
|
||||
import { DENOM } from "../../pages/_app";
|
||||
import { BondingInformation } from "./NodeBond";
|
||||
import { useGetBalance } from "../../hooks/useGetBalance";
|
||||
} from '../../common/helpers'
|
||||
import { DENOM } from '../../pages/_app'
|
||||
import { BondingInformation } from './NodeBond'
|
||||
import { useGetBalance } from '../../hooks/useGetBalance'
|
||||
|
||||
const DEFAULT_MIX_PORT = 1789;
|
||||
const DEFAULT_VERLOC_PORT = 1790;
|
||||
const DEFAULT_HTTP_API_PORT = 8000;
|
||||
const DEFAULT_CLIENTS_PORT = 9000;
|
||||
const DEFAULT_MIX_PORT = 1789
|
||||
const DEFAULT_VERLOC_PORT = 1790
|
||||
const DEFAULT_HTTP_API_PORT = 8000
|
||||
const DEFAULT_CLIENTS_PORT = 9000
|
||||
|
||||
type TBondNodeFormProps = {
|
||||
type: NodeType;
|
||||
minimumMixnodeBond: Coin;
|
||||
minimumGatewayBond: Coin;
|
||||
onSubmit: (event: any) => void;
|
||||
};
|
||||
type: NodeType
|
||||
minimumMixnodeBond: Coin
|
||||
minimumGatewayBond: Coin
|
||||
onSubmit: (event: any) => void
|
||||
}
|
||||
|
||||
type TFormInput = {
|
||||
amount: string;
|
||||
host: string;
|
||||
http_api_port: string;
|
||||
mixPort: string;
|
||||
verlocPort: string;
|
||||
sphinxKey: string;
|
||||
identityKey: string;
|
||||
version: string;
|
||||
location?: string;
|
||||
clientsPort?: string;
|
||||
httpApiPort?: string;
|
||||
};
|
||||
amount: string
|
||||
host: string
|
||||
http_api_port: string
|
||||
mixPort: string
|
||||
verlocPort: string
|
||||
sphinxKey: string
|
||||
identityKey: string
|
||||
version: string
|
||||
location?: string
|
||||
clientsPort?: string
|
||||
httpApiPort?: string
|
||||
}
|
||||
|
||||
export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
const classes = makeBasicStyle(theme);
|
||||
const classes = makeBasicStyle(theme)
|
||||
|
||||
const [validity, setValidity] = React.useState({
|
||||
validAmount: true,
|
||||
@@ -69,19 +69,19 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
|
||||
// gateway-specific:
|
||||
validClientsPort: true,
|
||||
});
|
||||
})
|
||||
|
||||
const [advancedShown, setAdvancedShown] = React.useState(false);
|
||||
const [allocationWarning, setAllocationWarning] = useState(false);
|
||||
const { getBalance, accountBalance } = useGetBalance();
|
||||
const [advancedShown, setAdvancedShown] = React.useState(false)
|
||||
const [allocationWarning, setAllocationWarning] = useState(false)
|
||||
const { getBalance, accountBalance } = useGetBalance()
|
||||
|
||||
useEffect(() => {
|
||||
getBalance();
|
||||
}, [getBalance]);
|
||||
getBalance()
|
||||
}, [getBalance])
|
||||
|
||||
const handleCheckboxToggle = () => {
|
||||
setAdvancedShown((prevSet) => !prevSet);
|
||||
};
|
||||
setAdvancedShown((prevSet) => !prevSet)
|
||||
}
|
||||
|
||||
const validateForm = ({
|
||||
amount,
|
||||
@@ -95,14 +95,14 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
httpApiPort,
|
||||
clientsPort,
|
||||
}: TFormInput): boolean => {
|
||||
let validAmount = validateAmount(amount);
|
||||
let validSphinxKey = validateKey(sphinxKey);
|
||||
let validIdentityKey = validateKey(identityKey);
|
||||
let validHost = validateHost(host);
|
||||
let validVersion = validateVersion(version);
|
||||
let validAmount = validateAmount(amount)
|
||||
let validSphinxKey = validateKey(sphinxKey)
|
||||
let validIdentityKey = validateKey(identityKey)
|
||||
let validHost = validateHost(host)
|
||||
let validVersion = validateVersion(version)
|
||||
|
||||
let validLocation =
|
||||
props.type == NodeType.Gateway ? validateLocation(location) : true;
|
||||
props.type == NodeType.Gateway ? validateLocation(location) : true
|
||||
|
||||
let newValidity = {
|
||||
validAmount: validAmount,
|
||||
@@ -111,16 +111,16 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
validHost: validHost,
|
||||
validVersion: validVersion,
|
||||
validLocation: validLocation,
|
||||
};
|
||||
}
|
||||
|
||||
if (advancedShown) {
|
||||
let validMixPort = validateRawPort(mixPort);
|
||||
let validMixPort = validateRawPort(mixPort)
|
||||
let validVerlocPort =
|
||||
props.type == NodeType.Mixnode ? validateRawPort(verlocPort) : true;
|
||||
props.type == NodeType.Mixnode ? validateRawPort(verlocPort) : true
|
||||
let validHttpApiPort =
|
||||
props.type == NodeType.Mixnode ? validateRawPort(httpApiPort) : true;
|
||||
props.type == NodeType.Mixnode ? validateRawPort(httpApiPort) : true
|
||||
let validClientsPort =
|
||||
props.type == NodeType.Gateway ? validateRawPort(clientsPort) : true;
|
||||
props.type == NodeType.Gateway ? validateRawPort(clientsPort) : true
|
||||
|
||||
newValidity = {
|
||||
...newValidity,
|
||||
@@ -130,46 +130,46 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
validHttpApiPort: validHttpApiPort,
|
||||
validClientsPort: validClientsPort,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setValidity((previousState) => {
|
||||
return { ...previousState, ...newValidity };
|
||||
});
|
||||
return { ...previousState, ...newValidity }
|
||||
})
|
||||
|
||||
// just AND everything together
|
||||
const reducer = (acc, current) => acc && current;
|
||||
const reducer = (acc, current) => acc && current
|
||||
return Object.entries(newValidity)
|
||||
.map((entry) => entry[1])
|
||||
.reduce(reducer, true);
|
||||
};
|
||||
.reduce(reducer, true)
|
||||
}
|
||||
|
||||
const validateAmount = (rawValue: string): boolean => {
|
||||
// tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc
|
||||
if (!basicRawCoinValueValidation(rawValue)) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
// this conversion seems really iffy but I'm not sure how to better approach it
|
||||
let nativeValueString = printableBalanceToNative(rawValue);
|
||||
let nativeValue = parseInt(nativeValueString);
|
||||
let nativeValueString = printableBalanceToNative(rawValue)
|
||||
let nativeValue = parseInt(nativeValueString)
|
||||
if (props.type == NodeType.Mixnode) {
|
||||
return nativeValue >= parseInt(props.minimumMixnodeBond.amount);
|
||||
return nativeValue >= parseInt(props.minimumMixnodeBond.amount)
|
||||
} else {
|
||||
return nativeValue >= parseInt(props.minimumGatewayBond.amount);
|
||||
return nativeValue >= parseInt(props.minimumGatewayBond.amount)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const validateKey = (key: string): boolean => {
|
||||
// it must be a valid base58 key
|
||||
try {
|
||||
const bytes = bs58.decode(key);
|
||||
const bytes = bs58.decode(key)
|
||||
// of length 32
|
||||
return bytes.length === 32;
|
||||
return bytes.length === 32
|
||||
} catch {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const validateHost = (host: string): boolean => {
|
||||
// I don't think that proper checks are in scope of the change here
|
||||
@@ -183,33 +183,33 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
// ipv6 can have multiple possible representations, but it needs to contain at least two colons
|
||||
// a hostname (in this case) needs to have a top level domain present
|
||||
|
||||
const dot_occurrences = host.split(".").length - 1;
|
||||
const colon_occurrences = host.split(":").length - 1;
|
||||
const dot_occurrences = host.split('.').length - 1
|
||||
const colon_occurrences = host.split(':').length - 1
|
||||
|
||||
if (dot_occurrences == 3) {
|
||||
// possible ipv4
|
||||
// make sure it has no ports attached!
|
||||
return colon_occurrences == 0;
|
||||
return colon_occurrences == 0
|
||||
} else if (colon_occurrences >= 2) {
|
||||
// possible ipv6
|
||||
return true;
|
||||
return true
|
||||
} else if (dot_occurrences >= 1) {
|
||||
// possible hostname
|
||||
// make sure it has no ports attached!
|
||||
return colon_occurrences == 0;
|
||||
return colon_occurrences == 0
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return false
|
||||
}
|
||||
|
||||
const validateVersion = (version: string): boolean => {
|
||||
// check if its a valid semver
|
||||
return semver.valid(version) && semver.minor(version) >= 11;
|
||||
};
|
||||
return semver.valid(version) && semver.minor(version) >= 11
|
||||
}
|
||||
|
||||
const validateLocation = (location: string): boolean => {
|
||||
// right now only perform the stupid check of whether the user copy-pasted the tooltip... (with or without brackets)
|
||||
return !location.trim().includes("physical location of your node");
|
||||
};
|
||||
return !location.trim().includes('physical location of your node')
|
||||
}
|
||||
|
||||
const constructMixnodeBondingInfo = ({
|
||||
amount,
|
||||
@@ -234,8 +234,8 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
identity_key: identityKey,
|
||||
version,
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const constructGatewayBondingInfo = (
|
||||
data: TFormInput
|
||||
@@ -253,25 +253,25 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
version: data.version,
|
||||
location: data.location,
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const submitForm = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
const target = event.target as unknown as TFormInput;
|
||||
event.preventDefault()
|
||||
const target = event.target as unknown as TFormInput
|
||||
|
||||
if (validateForm(target)) {
|
||||
if (props.type == NodeType.Mixnode) {
|
||||
return props.onSubmit(constructMixnodeBondingInfo(target));
|
||||
return props.onSubmit(constructMixnodeBondingInfo(target))
|
||||
} else {
|
||||
return props.onSubmit(constructGatewayBondingInfo(target));
|
||||
return props.onSubmit(constructGatewayBondingInfo(target))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let minimumBond = props.minimumMixnodeBond;
|
||||
let minimumBond = props.minimumMixnodeBond
|
||||
if (props.type == NodeType.Gateway) {
|
||||
minimumBond = props.minimumGatewayBond;
|
||||
minimumBond = props.minimumGatewayBond
|
||||
}
|
||||
|
||||
// if this whole interface wasn't to be completely redone in a month time, I would have definitely redone the form
|
||||
@@ -282,8 +282,8 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<Grid item xs={12} sm={8}>
|
||||
<TextField
|
||||
required
|
||||
id="amount"
|
||||
name="amount"
|
||||
id='amount'
|
||||
name='amount'
|
||||
label={`Amount to bond (minimum ${nativeToPrintable(
|
||||
minimumBond.amount
|
||||
)} ${minimumBond.denom})`}
|
||||
@@ -298,24 +298,24 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
fullWidth
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">{DENOM}</InputAdornment>
|
||||
<InputAdornment position='end'>{DENOM}</InputAdornment>
|
||||
),
|
||||
}}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
||||
if (
|
||||
typeof parseInt(e.target.value) === "number" &&
|
||||
typeof parseInt(e.target.value) === 'number' &&
|
||||
parseInt(accountBalance.amount) - parseInt(e.target.value) < 1
|
||||
) {
|
||||
setAllocationWarning(true);
|
||||
setAllocationWarning(true)
|
||||
} else {
|
||||
setAllocationWarning(false);
|
||||
setAllocationWarning(false)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
{allocationWarning && (
|
||||
<Grid item>
|
||||
<Alert severity="info">
|
||||
<Alert severity='info'>
|
||||
You're about to allocate all of your tokens. You may want to keep
|
||||
some in order to unbond this mixnode at a later time.
|
||||
</Alert>
|
||||
@@ -325,9 +325,9 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<TextField
|
||||
error={!validity.validIdentityKey}
|
||||
required
|
||||
id="identity"
|
||||
name="identity"
|
||||
label="Identity key"
|
||||
id='identity'
|
||||
name='identity'
|
||||
label='Identity key'
|
||||
fullWidth
|
||||
/>
|
||||
</Grid>
|
||||
@@ -335,12 +335,12 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<TextField
|
||||
error={!validity.validSphinxKey}
|
||||
required
|
||||
id="sphinxKey"
|
||||
name="sphinxKey"
|
||||
label="Sphinx key"
|
||||
id='sphinxKey'
|
||||
name='sphinxKey'
|
||||
label='Sphinx key'
|
||||
fullWidth
|
||||
{...(!validity.validSphinxKey
|
||||
? { helperText: "Enter a valid sphinx key" }
|
||||
? { helperText: 'Enter a valid sphinx key' }
|
||||
: {})}
|
||||
/>
|
||||
</Grid>
|
||||
@@ -348,12 +348,12 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<TextField
|
||||
error={!validity.validHost}
|
||||
required
|
||||
id="host"
|
||||
name="host"
|
||||
label="Host"
|
||||
id='host'
|
||||
name='host'
|
||||
label='Host'
|
||||
fullWidth
|
||||
{...(!validity.validHost
|
||||
? { helperText: "Enter a valid IP or a hostname (without port)" }
|
||||
? { helperText: 'Enter a valid IP or a hostname (without port)' }
|
||||
: {})}
|
||||
/>
|
||||
</Grid>
|
||||
@@ -364,12 +364,12 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<TextField
|
||||
error={!validity.validLocation}
|
||||
required
|
||||
id="location"
|
||||
name="location"
|
||||
label="Location"
|
||||
id='location'
|
||||
name='location'
|
||||
label='Location'
|
||||
fullWidth
|
||||
{...(!validity.validLocation
|
||||
? { helperText: "Enter a valid location of your node" }
|
||||
? { helperText: 'Enter a valid location of your node' }
|
||||
: {})}
|
||||
/>
|
||||
)}
|
||||
@@ -379,14 +379,14 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<TextField
|
||||
error={!validity.validVersion}
|
||||
required
|
||||
id="version"
|
||||
name="version"
|
||||
label="Version"
|
||||
id='version'
|
||||
name='version'
|
||||
label='Version'
|
||||
fullWidth
|
||||
{...(!validity.validVersion
|
||||
? {
|
||||
helperText:
|
||||
"Enter a valid version (min. 0.11.0), like 0.11.0",
|
||||
'Enter a valid version (min. 0.11.0), like 0.11.0',
|
||||
}
|
||||
: {})}
|
||||
/>
|
||||
@@ -400,37 +400,37 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
onChange={handleCheckboxToggle}
|
||||
/>
|
||||
}
|
||||
label="Show advanced options"
|
||||
label='Show advanced options'
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{advancedShown && (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<Grid item xs={12} sm={4}>
|
||||
<TextField
|
||||
error={!validity.validMixPort}
|
||||
variant="outlined"
|
||||
id="mixPort"
|
||||
name="mixPort"
|
||||
label="Mix Port"
|
||||
variant='outlined'
|
||||
id='mixPort'
|
||||
name='mixPort'
|
||||
label='Mix Port'
|
||||
fullWidth
|
||||
defaultValue={DEFAULT_MIX_PORT}
|
||||
{...(!validity.validMixPort
|
||||
? { helperText: "Enter a valid version, like 0.10.0" }
|
||||
? { helperText: 'Enter a valid version, like 0.10.0' }
|
||||
: {})}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{/*yes, I also hate so many layers of indentation here*/}
|
||||
{props.type === NodeType.Mixnode ? (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<Grid item xs={12} sm={4}>
|
||||
<TextField
|
||||
error={!validity.validVerlocPort}
|
||||
variant="outlined"
|
||||
id="verlocPort"
|
||||
name="verlocPort"
|
||||
label="Verloc Port"
|
||||
variant='outlined'
|
||||
id='verlocPort'
|
||||
name='verlocPort'
|
||||
label='Verloc Port'
|
||||
fullWidth
|
||||
defaultValue={DEFAULT_VERLOC_PORT}
|
||||
/>
|
||||
@@ -439,42 +439,42 @@ export default function BondNodeForm(props: TBondNodeFormProps) {
|
||||
<Grid item xs={12} sm={4}>
|
||||
<TextField
|
||||
error={!validity.validHttpApiPort}
|
||||
variant="outlined"
|
||||
id="httpApiPort"
|
||||
name="httpApiPort"
|
||||
label="HTTP API Port"
|
||||
variant='outlined'
|
||||
id='httpApiPort'
|
||||
name='httpApiPort'
|
||||
label='HTTP API Port'
|
||||
fullWidth
|
||||
defaultValue={DEFAULT_HTTP_API_PORT}
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
</>
|
||||
) : (
|
||||
<Grid item xs={12} sm={4}>
|
||||
<TextField
|
||||
error={!validity.validClientsPort}
|
||||
variant="outlined"
|
||||
id="clientsPort"
|
||||
name="clientsPort"
|
||||
label="client WS API Port"
|
||||
variant='outlined'
|
||||
id='clientsPort'
|
||||
name='clientsPort'
|
||||
label='client WS API Port'
|
||||
fullWidth
|
||||
defaultValue={DEFAULT_CLIENTS_PORT}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</React.Fragment>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<div className={classes.buttons}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
variant='contained'
|
||||
color='primary'
|
||||
type='submit'
|
||||
className={classes.button}
|
||||
>
|
||||
Bond
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,163 +1,184 @@
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Grid, LinearProgress, Paper } from '@material-ui/core';
|
||||
import { Gateway, MixNode } from '@nymproject/nym-validator-client/dist/types';
|
||||
import Confirmation from "../Confirmation";
|
||||
import { ValidatorClientContext } from "../../contexts/ValidatorClient";
|
||||
import NoClientError from "../NoClientError";
|
||||
import { useRouter } from "next/router";
|
||||
import BondNodeForm from "./BondNodeForm";
|
||||
import { NodeType } from "../../common/node";
|
||||
import Link from "../Link";
|
||||
import { theme } from "../../lib/theme";
|
||||
import { checkNodesOwnership, makeBasicStyle } from "../../common/helpers";
|
||||
import NodeTypeChooser from "../NodeTypeChooser";
|
||||
import ExecFeeNotice from "../ExecFeeNotice";
|
||||
import { printableBalanceToNative } from "@nymproject/nym-validator-client/dist/currency";
|
||||
import { coin } from "@nymproject/nym-validator-client";
|
||||
import { UDENOM } from "../../pages/_app";
|
||||
import React, { useContext, useEffect } from 'react'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import { Grid, LinearProgress, Paper } from '@material-ui/core'
|
||||
import { Gateway, MixNode } from '@nymproject/nym-validator-client/dist/types'
|
||||
import Confirmation from '../Confirmation'
|
||||
import { ValidatorClientContext } from '../../contexts/ValidatorClient'
|
||||
import NoClientError from '../NoClientError'
|
||||
import { useRouter } from 'next/router'
|
||||
import BondNodeForm from './BondNodeForm'
|
||||
import { NodeType } from '../../common/node'
|
||||
import Link from '../Link'
|
||||
import { theme } from '../../lib/theme'
|
||||
import { checkNodesOwnership, makeBasicStyle } from '../../common/helpers'
|
||||
import NodeTypeChooser from '../NodeTypeChooser'
|
||||
import ExecFeeNotice from '../ExecFeeNotice'
|
||||
import { printableBalanceToNative } from '@nymproject/nym-validator-client/dist/currency'
|
||||
import { coin } from '@nymproject/nym-validator-client'
|
||||
import { UDENOM } from '../../pages/_app'
|
||||
|
||||
export type BondingInformation = {
|
||||
amount: string,
|
||||
nodeDetails: MixNode | Gateway;
|
||||
amount: string
|
||||
nodeDetails: MixNode | Gateway
|
||||
}
|
||||
|
||||
const BondNode = () => {
|
||||
const classes = makeBasicStyle(theme);
|
||||
const router = useRouter()
|
||||
const {client} = useContext(ValidatorClientContext)
|
||||
const classes = makeBasicStyle(theme)
|
||||
const router = useRouter()
|
||||
const { client } = useContext(ValidatorClientContext)
|
||||
|
||||
const [bondingStarted, setBondingStarted] = React.useState(false)
|
||||
const [bondingFinished, setBondingFinished] = React.useState(false)
|
||||
const [bondingError, setBondingError] = React.useState(null)
|
||||
const [bondingStarted, setBondingStarted] = React.useState(false)
|
||||
const [bondingFinished, setBondingFinished] = React.useState(false)
|
||||
const [bondingError, setBondingError] = React.useState(null)
|
||||
|
||||
const [checkedOwnership, setCheckedOwnership] = React.useState(false)
|
||||
const [ownsMixnode, setOwnsMixnode] = React.useState(false)
|
||||
const [ownsGateway, setOwnsGateway] = React.useState(false)
|
||||
const [checkedOwnership, setCheckedOwnership] = React.useState(false)
|
||||
const [ownsMixnode, setOwnsMixnode] = React.useState(false)
|
||||
const [ownsGateway, setOwnsGateway] = React.useState(false)
|
||||
|
||||
const [minimumMixnodeBond, setMinimumMixnodeBond] = React.useState(null)
|
||||
const [minimumGatewayBond, setMinimumGatewayBond] = React.useState(null)
|
||||
const [minimumMixnodeBond, setMinimumMixnodeBond] = React.useState(null)
|
||||
const [minimumGatewayBond, setMinimumGatewayBond] = React.useState(null)
|
||||
|
||||
const [nodeType, setNodeType] = React.useState(NodeType.Mixnode)
|
||||
const [nodeType, setNodeType] = React.useState(NodeType.Mixnode)
|
||||
|
||||
useEffect(() => {
|
||||
const getInitialData = async () => {
|
||||
if (client === null) {
|
||||
await router.push("/")
|
||||
} else {
|
||||
const nodeOwnership = await checkNodesOwnership(client)
|
||||
setOwnsMixnode(nodeOwnership.ownsMixnode)
|
||||
setOwnsGateway(nodeOwnership.ownsGateway)
|
||||
useEffect(() => {
|
||||
const getInitialData = async () => {
|
||||
if (client === null) {
|
||||
await router.push('/')
|
||||
} else {
|
||||
const nodeOwnership = await checkNodesOwnership(client)
|
||||
setOwnsMixnode(nodeOwnership.ownsMixnode)
|
||||
setOwnsGateway(nodeOwnership.ownsGateway)
|
||||
|
||||
const minimumMixnodeBond = await client.minimumMixnodeBond()
|
||||
setMinimumMixnodeBond(minimumMixnodeBond)
|
||||
const minimumGatewayBond = await client.minimumGatewayBond()
|
||||
setMinimumGatewayBond(minimumGatewayBond)
|
||||
const minimumMixnodeBond = await client.minimumMixnodeBond()
|
||||
setMinimumMixnodeBond(minimumMixnodeBond)
|
||||
const minimumGatewayBond = await client.minimumGatewayBond()
|
||||
setMinimumGatewayBond(minimumGatewayBond)
|
||||
|
||||
setCheckedOwnership(true)
|
||||
}
|
||||
}
|
||||
getInitialData()
|
||||
}, [client])
|
||||
setCheckedOwnership(true)
|
||||
}
|
||||
}
|
||||
getInitialData()
|
||||
}, [client])
|
||||
|
||||
const bondNode = async (bondingInformation: BondingInformation) => {
|
||||
setBondingStarted(true)
|
||||
console.log(`BOND button pressed`);
|
||||
const bondNode = async (bondingInformation: BondingInformation) => {
|
||||
setBondingStarted(true)
|
||||
console.log(`BOND button pressed`)
|
||||
|
||||
console.log(bondingInformation)
|
||||
let amountValue = parseInt(printableBalanceToNative(bondingInformation.amount))
|
||||
let amount = coin(amountValue, UDENOM)
|
||||
console.log(bondingInformation)
|
||||
let amountValue = parseInt(
|
||||
printableBalanceToNative(bondingInformation.amount)
|
||||
)
|
||||
let amount = coin(amountValue, UDENOM)
|
||||
|
||||
console.log(bondingInformation.nodeDetails)
|
||||
console.log(bondingInformation.nodeDetails)
|
||||
|
||||
if (nodeType == NodeType.Mixnode) {
|
||||
let mixnode = (bondingInformation.nodeDetails as MixNode)
|
||||
client.bondMixnode(mixnode, amount).then((value => {
|
||||
console.log("bonded mixnode!", value)
|
||||
})).catch(setBondingError).finally(() => setBondingFinished(true))
|
||||
} else {
|
||||
let gateway = (bondingInformation.nodeDetails as Gateway)
|
||||
client.bondGateway(gateway, amount).then((value => {
|
||||
console.log("bonded gateway!", value)
|
||||
})).catch(setBondingError).finally(() => setBondingFinished(true))
|
||||
}
|
||||
if (nodeType == NodeType.Mixnode) {
|
||||
let mixnode = bondingInformation.nodeDetails as MixNode
|
||||
client
|
||||
.bondMixnode(mixnode, amount)
|
||||
.then((value) => {
|
||||
console.log('bonded mixnode!', value)
|
||||
})
|
||||
.catch(setBondingError)
|
||||
.finally(() => setBondingFinished(true))
|
||||
} else {
|
||||
let gateway = bondingInformation.nodeDetails as Gateway
|
||||
client
|
||||
.bondGateway(gateway, amount)
|
||||
.then((value) => {
|
||||
console.log('bonded gateway!', value)
|
||||
})
|
||||
.catch(setBondingError)
|
||||
.finally(() => setBondingFinished(true))
|
||||
}
|
||||
}
|
||||
|
||||
const getBondContent = () => {
|
||||
// we're not signed in
|
||||
if (client === null) {
|
||||
return <NoClientError />
|
||||
}
|
||||
|
||||
const getBondContent = () => {
|
||||
// we're not signed in
|
||||
if (client === null) {
|
||||
return (<NoClientError/>)
|
||||
}
|
||||
|
||||
// we haven't checked whether we actually already own a node
|
||||
if (!checkedOwnership) {
|
||||
return (<LinearProgress/>)
|
||||
}
|
||||
|
||||
// we already own a mixnode
|
||||
if (ownsMixnode) {
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography gutterBottom>
|
||||
You have already have a bonded mixnode. If you wish to bond a different one, you need to
|
||||
first <Link href="/unbond">unbond the existing one</Link>.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
// we already own a gateway
|
||||
if (ownsGateway) {
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography gutterBottom>
|
||||
You have already have a bonded gateway. If you wish to bond a different one, you need to
|
||||
first <Link href="/unbond">unbond the existing one</Link>.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
// we haven't clicked bond button yet
|
||||
if (!bondingStarted) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<NodeTypeChooser nodeType={nodeType} setNodeType={setNodeType}/>
|
||||
<BondNodeForm onSubmit={bondNode} type={nodeType} minimumGatewayBond={minimumGatewayBond}
|
||||
minimumMixnodeBond={minimumMixnodeBond}/>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
// We started bonding
|
||||
return (
|
||||
<Confirmation
|
||||
finished={bondingFinished}
|
||||
error={bondingError}
|
||||
progressMessage={`${nodeType} bonding is in progress...`}
|
||||
successMessage={`${nodeType} bonding was successful!`}
|
||||
failureMessage={`Failed to bond the ${nodeType}!`}
|
||||
/>
|
||||
)
|
||||
// we haven't checked whether we actually already own a node
|
||||
if (!checkedOwnership) {
|
||||
return <LinearProgress />
|
||||
}
|
||||
|
||||
// we already own a mixnode
|
||||
if (ownsMixnode) {
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography gutterBottom>
|
||||
You have already have a bonded mixnode. If you wish to bond a
|
||||
different one, you need to first{' '}
|
||||
<Link href='/unbond'>unbond the existing one</Link>.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
// we already own a gateway
|
||||
if (ownsGateway) {
|
||||
return (
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography gutterBottom>
|
||||
You have already have a bonded gateway. If you wish to bond a
|
||||
different one, you need to first{' '}
|
||||
<Link href='/unbond'>unbond the existing one</Link>.
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
// we haven't clicked bond button yet
|
||||
if (!bondingStarted) {
|
||||
return (
|
||||
<>
|
||||
<NodeTypeChooser nodeType={nodeType} setNodeType={setNodeType} />
|
||||
<BondNodeForm
|
||||
onSubmit={bondNode}
|
||||
type={nodeType}
|
||||
minimumGatewayBond={minimumGatewayBond}
|
||||
minimumMixnodeBond={minimumMixnodeBond}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// We started bonding
|
||||
return (
|
||||
<React.Fragment>
|
||||
<main className={classes.layout}>
|
||||
<Paper className={classes.paper}>
|
||||
<ExecFeeNotice name="bonding"/>
|
||||
<Typography component="h1" variant="h4" align="center" className={classes.wrapper}>
|
||||
Bond a {nodeType}
|
||||
</Typography>
|
||||
{getBondContent()}
|
||||
</Paper>
|
||||
</main>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
<Confirmation
|
||||
isLoading={bondingFinished}
|
||||
error={bondingError}
|
||||
progressMessage={`${nodeType} bonding is in progress...`}
|
||||
successMessage={`${nodeType} bonding was successful!`}
|
||||
failureMessage={`Failed to bond the ${nodeType}!`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default BondNode;
|
||||
return (
|
||||
<>
|
||||
<main className={classes.layout}>
|
||||
<Paper className={classes.paper}>
|
||||
<ExecFeeNotice name='bonding' />
|
||||
<Typography
|
||||
component='h1'
|
||||
variant='h4'
|
||||
align='center'
|
||||
className={classes.wrapper}
|
||||
>
|
||||
Bond a {nodeType}
|
||||
</Typography>
|
||||
{getBondContent()}
|
||||
</Paper>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default BondNode
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import React, { useState, useEffect, ChangeEvent } from "react";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { Button, InputAdornment } from "@material-ui/core";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import { DENOM } from "../../pages/_app";
|
||||
import { theme } from "../../lib/theme";
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
import { Button, InputAdornment } from '@material-ui/core'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import { Alert } from '@material-ui/lab'
|
||||
import { DENOM } from '../../pages/_app'
|
||||
import { theme } from '../../lib/theme'
|
||||
import {
|
||||
basicRawCoinValueValidation,
|
||||
makeBasicStyle,
|
||||
validateIdentityKey,
|
||||
} from "../../common/helpers";
|
||||
import { useGetBalance } from "../../hooks/useGetBalance";
|
||||
import { Alert } from "@material-ui/lab";
|
||||
} from '../../common/helpers'
|
||||
import { useGetBalance } from '../../hooks/useGetBalance'
|
||||
|
||||
type DelegateFormProps = {
|
||||
onSubmit: (event: any) => void;
|
||||
};
|
||||
onSubmit: (event: any) => void
|
||||
}
|
||||
|
||||
export default function DelegateForm(props: DelegateFormProps) {
|
||||
const classes = makeBasicStyle(theme);
|
||||
const classes = makeBasicStyle(theme)
|
||||
|
||||
const [validAmount, setValidAmount] = useState(true);
|
||||
const [validIdentity, setValidIdentity] = useState(true);
|
||||
const [allocationWarning, setAllocationWarning] = useState(false);
|
||||
const { getBalance, accountBalance } = useGetBalance();
|
||||
const [validAmount, setValidAmount] = useState(true)
|
||||
const [validIdentity, setValidIdentity] = useState(true)
|
||||
const [allocationWarning, setAllocationWarning] = useState(false)
|
||||
const { getBalance, accountBalance } = useGetBalance()
|
||||
|
||||
useEffect(() => {
|
||||
getBalance();
|
||||
}, [getBalance]);
|
||||
getBalance()
|
||||
}, [getBalance])
|
||||
|
||||
// const [checkboxSet, setCheckboxSet] = React.useState(false)
|
||||
|
||||
@@ -38,40 +38,40 @@ export default function DelegateForm(props: DelegateFormProps) {
|
||||
// don't ask me about that. javascript works in mysterious ways
|
||||
// and this is apparently a good way of checking if string
|
||||
// is purely made of numeric characters
|
||||
let parsed = +event.target.value;
|
||||
let parsed = +event.target.value
|
||||
if (isNaN(parsed)) {
|
||||
setValidAmount(false);
|
||||
setValidAmount(false)
|
||||
} else {
|
||||
if (parsed > 0 && parseInt(accountBalance.amount) - parsed < 1) {
|
||||
setAllocationWarning(true);
|
||||
setAllocationWarning(true)
|
||||
} else {
|
||||
setAllocationWarning(false);
|
||||
setAllocationWarning(false)
|
||||
}
|
||||
setValidAmount(true);
|
||||
setValidAmount(true)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const validateForm = (event: any): boolean => {
|
||||
let validIdentity = validateIdentityKey(event.target.identity.value);
|
||||
let validAmount = validateAmount(event.target.amount.value);
|
||||
let validIdentity = validateIdentityKey(event.target.identity.value)
|
||||
let validAmount = validateAmount(event.target.amount.value)
|
||||
|
||||
setValidIdentity(validIdentity);
|
||||
setValidAmount(validAmount);
|
||||
setValidIdentity(validIdentity)
|
||||
setValidAmount(validAmount)
|
||||
|
||||
return validIdentity && validAmount;
|
||||
};
|
||||
return validIdentity && validAmount
|
||||
}
|
||||
|
||||
const validateAmount = (rawAmount: string): boolean => {
|
||||
return basicRawCoinValueValidation(rawAmount);
|
||||
};
|
||||
return basicRawCoinValueValidation(rawAmount)
|
||||
}
|
||||
|
||||
const submitForm = (event: any) => {
|
||||
event.preventDefault();
|
||||
event.preventDefault()
|
||||
|
||||
if (validateForm(event)) {
|
||||
return props.onSubmit(event);
|
||||
return props.onSubmit(event)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={submitForm}>
|
||||
@@ -79,13 +79,13 @@ export default function DelegateForm(props: DelegateFormProps) {
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
required
|
||||
id="identity"
|
||||
name="identity"
|
||||
label="Node identity"
|
||||
id='identity'
|
||||
name='identity'
|
||||
label='Node identity'
|
||||
error={!validIdentity}
|
||||
helperText={
|
||||
validIdentity
|
||||
? ""
|
||||
? ''
|
||||
: "Please enter a valid identity like '824WyExLUWvLE2mpSHBatN4AoByuLzfnHFeHWiBYzg4z'"
|
||||
}
|
||||
fullWidth
|
||||
@@ -95,23 +95,23 @@ export default function DelegateForm(props: DelegateFormProps) {
|
||||
<Grid item xs={12} sm={6}>
|
||||
<TextField
|
||||
required
|
||||
id="amount"
|
||||
name="amount"
|
||||
label="Amount to delegate"
|
||||
id='amount'
|
||||
name='amount'
|
||||
label='Amount to delegate'
|
||||
error={!validAmount}
|
||||
helperText={validAmount ? "" : "Please enter a valid amount"}
|
||||
helperText={validAmount ? '' : 'Please enter a valid amount'}
|
||||
onChange={handleAmountChange}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">{DENOM}</InputAdornment>
|
||||
<InputAdornment position='end'>{DENOM}</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
{allocationWarning && (
|
||||
<Grid item>
|
||||
<Alert severity="info">
|
||||
<Alert severity='info'>
|
||||
You're about to allocate all of your tokens. You may want to keep
|
||||
some in order to unbond this mixnode at a later time.
|
||||
</Alert>
|
||||
@@ -133,14 +133,14 @@ export default function DelegateForm(props: DelegateFormProps) {
|
||||
</Grid>
|
||||
<div className={classes.buttons}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
variant='contained'
|
||||
color='primary'
|
||||
type='submit'
|
||||
className={classes.button}
|
||||
>
|
||||
Delegate stake
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,112 +1,124 @@
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import { Paper } from "@material-ui/core";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { useRouter } from "next/router";
|
||||
import { ValidatorClientContext } from "../../contexts/ValidatorClient";
|
||||
import { NodeType } from "../../common/node";
|
||||
import NoClientError from "../NoClientError";
|
||||
import Confirmation from "../Confirmation";
|
||||
import DelegateForm from "./DelegateForm";
|
||||
import { printableBalanceToNative } from "@nymproject/nym-validator-client/dist/currency";
|
||||
import { Coin } from "@cosmjs/launchpad";
|
||||
import { coin, printableCoin } from "@nymproject/nym-validator-client";
|
||||
import { UDENOM } from "../../pages/_app";
|
||||
import { theme } from "../../lib/theme";
|
||||
import { makeBasicStyle } from "../../common/helpers";
|
||||
import NodeTypeChooser from "../NodeTypeChooser";
|
||||
import ExecFeeNotice from "../ExecFeeNotice";
|
||||
import React, { useContext, useEffect } from 'react'
|
||||
import { Paper } from '@material-ui/core'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import { useRouter } from 'next/router'
|
||||
import { ValidatorClientContext } from '../../contexts/ValidatorClient'
|
||||
import { NodeType } from '../../common/node'
|
||||
import NoClientError from '../NoClientError'
|
||||
import Confirmation from '../Confirmation'
|
||||
import DelegateForm from './DelegateForm'
|
||||
import { printableBalanceToNative } from '@nymproject/nym-validator-client/dist/currency'
|
||||
import { Coin } from '@cosmjs/launchpad'
|
||||
import { coin, printableCoin } from '@nymproject/nym-validator-client'
|
||||
import { UDENOM } from '../../pages/_app'
|
||||
import { theme } from '../../lib/theme'
|
||||
import { makeBasicStyle } from '../../common/helpers'
|
||||
import NodeTypeChooser from '../NodeTypeChooser'
|
||||
import ExecFeeNotice from '../ExecFeeNotice'
|
||||
|
||||
const DelegateToNode = () => {
|
||||
const classes = makeBasicStyle(theme);
|
||||
const router = useRouter()
|
||||
const {client} = useContext(ValidatorClientContext)
|
||||
const classes = makeBasicStyle(theme)
|
||||
const router = useRouter()
|
||||
const { client } = useContext(ValidatorClientContext)
|
||||
|
||||
const [delegationStarted, setDelegationStarted] = React.useState(false)
|
||||
const [delegationFinished, setDelegationFinished] = React.useState(false)
|
||||
const [delegationError, setDelegationError] = React.useState(null)
|
||||
const [delegationStarted, setDelegationStarted] = React.useState(false)
|
||||
const [delegationFinished, setDelegationFinished] = React.useState(false)
|
||||
const [delegationError, setDelegationError] = React.useState(null)
|
||||
|
||||
const [nodeType, setNodeType] = React.useState(NodeType.Mixnode)
|
||||
const [stakeValue, setStakeValue] = React.useState("0 HAL")
|
||||
const [nodeIdentity, setNodeIdentity] = React.useState("")
|
||||
const [nodeType, setNodeType] = React.useState(NodeType.Mixnode)
|
||||
const [stakeValue, setStakeValue] = React.useState('0 HAL')
|
||||
const [nodeIdentity, setNodeIdentity] = React.useState('')
|
||||
|
||||
useEffect(() => {
|
||||
const checkClient = async () => {
|
||||
if (client === null) {
|
||||
await router.push("/")
|
||||
}
|
||||
}
|
||||
checkClient()
|
||||
}, [client])
|
||||
useEffect(() => {
|
||||
const checkClient = async () => {
|
||||
if (client === null) {
|
||||
await router.push('/')
|
||||
}
|
||||
}
|
||||
checkClient()
|
||||
}, [client])
|
||||
|
||||
const getDelegationValue = (raw: string): Coin => {
|
||||
let native = printableBalanceToNative(raw)
|
||||
return coin(parseInt(native), UDENOM)
|
||||
const getDelegationValue = (raw: string): Coin => {
|
||||
let native = printableBalanceToNative(raw)
|
||||
return coin(parseInt(native), UDENOM)
|
||||
}
|
||||
|
||||
const delegateToNode = async (event) => {
|
||||
event.preventDefault()
|
||||
console.log(`DELEGATE button pressed`)
|
||||
|
||||
const nodeIdentity = event.target.identity.value
|
||||
const delegationValue = getDelegationValue(event.target.amount.value)
|
||||
|
||||
setNodeIdentity(nodeIdentity)
|
||||
setStakeValue(printableCoin(delegationValue))
|
||||
setDelegationStarted(true)
|
||||
|
||||
if (nodeType == NodeType.Mixnode) {
|
||||
client
|
||||
.delegateToMixnode(nodeIdentity, delegationValue)
|
||||
.then((value) => {
|
||||
console.log('delegated to mixnode!', value)
|
||||
})
|
||||
.catch(setDelegationError)
|
||||
.finally(() => setDelegationFinished(true))
|
||||
} else {
|
||||
client
|
||||
.delegateToGateway(nodeIdentity, delegationValue)
|
||||
.then((value) => {
|
||||
console.log('delegated to gateway!', value)
|
||||
})
|
||||
.catch(setDelegationError)
|
||||
.finally(() => setDelegationFinished(true))
|
||||
}
|
||||
}
|
||||
|
||||
const getDelegationContent = () => {
|
||||
// we're not signed in
|
||||
if (client === null) {
|
||||
return <NoClientError />
|
||||
}
|
||||
|
||||
const delegateToNode = async (event) => {
|
||||
event.preventDefault();
|
||||
console.log(`DELEGATE button pressed`);
|
||||
|
||||
const nodeIdentity = event.target.identity.value;
|
||||
const delegationValue = getDelegationValue(event.target.amount.value)
|
||||
|
||||
setNodeIdentity(nodeIdentity)
|
||||
setStakeValue(printableCoin(delegationValue))
|
||||
setDelegationStarted(true)
|
||||
|
||||
if (nodeType == NodeType.Mixnode) {
|
||||
client.delegateToMixnode(nodeIdentity, delegationValue).then((value => {
|
||||
console.log("delegated to mixnode!", value)
|
||||
})).catch(setDelegationError).finally(() => setDelegationFinished(true))
|
||||
} else {
|
||||
client.delegateToGateway(nodeIdentity, delegationValue).then((value => {
|
||||
console.log("delegated to gateway!", value)
|
||||
})).catch(setDelegationError).finally(() => setDelegationFinished(true))
|
||||
}
|
||||
}
|
||||
|
||||
const getDelegationContent = () => {
|
||||
// we're not signed in
|
||||
if (client === null) {
|
||||
return (<NoClientError/>)
|
||||
}
|
||||
|
||||
// we haven't clicked delegate button yet
|
||||
if (!delegationStarted) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<NodeTypeChooser nodeType={nodeType} setNodeType={setNodeType}/>
|
||||
<DelegateForm onSubmit={delegateToNode}/>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
// We started delegation
|
||||
return (
|
||||
<Confirmation
|
||||
finished={delegationFinished}
|
||||
error={delegationError}
|
||||
progressMessage={`Delegating stake on ${nodeType} ${nodeIdentity} is in progress...`}
|
||||
successMessage={`Successfully delegated ${stakeValue} stake on ${nodeType} ${nodeIdentity}`}
|
||||
failureMessage={`Failed to delegate to a ${nodeType}!`}
|
||||
/>
|
||||
)
|
||||
// we haven't clicked delegate button yet
|
||||
if (!delegationStarted) {
|
||||
return (
|
||||
<>
|
||||
<NodeTypeChooser nodeType={nodeType} setNodeType={setNodeType} />
|
||||
<DelegateForm onSubmit={delegateToNode} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// We started delegation
|
||||
return (
|
||||
<React.Fragment>
|
||||
<main className={classes.layout}>
|
||||
<Paper className={classes.paper}>
|
||||
<ExecFeeNotice name={"delegating stake"}/>
|
||||
<Typography component="h1" variant="h4" align="center" className={classes.wrapper}>
|
||||
Delegate to {nodeType}
|
||||
</Typography>
|
||||
{getDelegationContent()}
|
||||
</Paper>
|
||||
</main>
|
||||
</React.Fragment>
|
||||
);
|
||||
<Confirmation
|
||||
finished={delegationFinished}
|
||||
error={delegationError}
|
||||
progressMessage={`Delegating stake on ${nodeType} ${nodeIdentity} is in progress...`}
|
||||
successMessage={`Successfully delegated ${stakeValue} stake on ${nodeType} ${nodeIdentity}`}
|
||||
failureMessage={`Failed to delegate to a ${nodeType}!`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className={classes.layout}>
|
||||
<Paper className={classes.paper}>
|
||||
<ExecFeeNotice name={'delegating stake'} />
|
||||
<Typography
|
||||
component='h1'
|
||||
variant='h4'
|
||||
align='center'
|
||||
className={classes.wrapper}
|
||||
>
|
||||
Delegate to {nodeType}
|
||||
</Typography>
|
||||
{getDelegationContent()}
|
||||
</Paper>
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default DelegateToNode;
|
||||
export default DelegateToNode
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { useRouter } from "next/router";
|
||||
import { ValidatorClientContext } from "../contexts/ValidatorClient";
|
||||
import MainNav from "../components/MainNav";
|
||||
import Confirmation from "../components/Confirmation";
|
||||
import NoClientError from "../components/NoClientError";
|
||||
import { useGetBalance } from "../hooks/useGetBalance";
|
||||
import React, { useContext, useEffect } from 'react'
|
||||
import Paper from '@material-ui/core/Paper'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import RefreshIcon from '@material-ui/icons/Refresh'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { useRouter } from 'next/router'
|
||||
import { ValidatorClientContext } from '../contexts/ValidatorClient'
|
||||
import MainNav from '../components/MainNav'
|
||||
import Confirmation from '../components/Confirmation'
|
||||
import NoClientError from '../components/NoClientError'
|
||||
import { useGetBalance } from '../hooks/useGetBalance'
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
appBar: {
|
||||
position: "relative",
|
||||
position: 'relative',
|
||||
},
|
||||
layout: {
|
||||
width: "auto",
|
||||
width: 'auto',
|
||||
marginLeft: theme.spacing(2),
|
||||
marginRight: theme.spacing(2),
|
||||
[theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {
|
||||
width: 600,
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
marginLeft: 'auto',
|
||||
marginRight: 'auto',
|
||||
},
|
||||
},
|
||||
paper: {
|
||||
@@ -36,61 +36,61 @@ const useStyles = makeStyles((theme) => ({
|
||||
},
|
||||
},
|
||||
buttons: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing(3),
|
||||
marginLeft: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
}))
|
||||
|
||||
export default function CheckBalance() {
|
||||
const classes = useStyles();
|
||||
const router = useRouter();
|
||||
const classes = useStyles()
|
||||
const router = useRouter()
|
||||
|
||||
const { client } = useContext(ValidatorClientContext);
|
||||
const { client } = useContext(ValidatorClientContext)
|
||||
const { getBalance, isBalanceLoading, balanceCheckError, printedBalance } =
|
||||
useGetBalance();
|
||||
useGetBalance()
|
||||
|
||||
useEffect(() => {
|
||||
const updateBalance = async () => {
|
||||
if (client === null) {
|
||||
await router.push("/");
|
||||
await router.push('/')
|
||||
} else {
|
||||
await getBalance();
|
||||
await getBalance()
|
||||
}
|
||||
};
|
||||
updateBalance();
|
||||
}, [client]);
|
||||
}
|
||||
updateBalance()
|
||||
}, [client])
|
||||
|
||||
const balanceMessage = `Current account balance is ${printedBalance}`;
|
||||
const balanceMessage = `Current account balance is ${printedBalance}`
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<MainNav />
|
||||
<main className={classes.layout}>
|
||||
<Paper className={classes.paper}>
|
||||
<Typography component="h1" variant="h4" align="center">
|
||||
<Typography component='h1' variant='h4' align='center'>
|
||||
Check Balance
|
||||
</Typography>
|
||||
|
||||
{client === null ? (
|
||||
<NoClientError />
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<Confirmation
|
||||
isLoading={isBalanceLoading}
|
||||
error={balanceCheckError}
|
||||
progressMessage="Checking balance..."
|
||||
progressMessage='Checking balance...'
|
||||
successMessage={balanceMessage}
|
||||
failureMessage="Failed to check the account balance!"
|
||||
failureMessage='Failed to check the account balance!'
|
||||
/>
|
||||
<div className={classes.buttons}>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
variant='contained'
|
||||
color='primary'
|
||||
type='submit'
|
||||
onClick={getBalance}
|
||||
disabled={isBalanceLoading}
|
||||
className={classes.button}
|
||||
@@ -99,10 +99,10 @@ export default function CheckBalance() {
|
||||
Refresh
|
||||
</Button>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
</>
|
||||
)}
|
||||
</Paper>
|
||||
</main>
|
||||
</React.Fragment>
|
||||
);
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user