From e130131f16c0b1fd34ebd10b0a44235481ded9fe Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Wed, 15 Sep 2021 20:37:24 +0100 Subject: [PATCH] finish bonding and unbonding setup --- .../src/components/NodeTypeSelector.tsx | 4 ++ tauri-wallet/src/context/main.tsx | 2 +- tauri-wallet/src/hooks/useCheckOwnership.ts | 39 +++++++++++ tauri-wallet/src/hooks/useGetBalance.tsx | 6 +- tauri-wallet/src/requests/index.ts | 20 ++++++ tauri-wallet/src/routes/bond/BondForm.tsx | 70 +++++++++++-------- tauri-wallet/src/routes/bond/index.tsx | 59 +++++++++++----- tauri-wallet/src/routes/sign-in.tsx | 4 +- tauri-wallet/src/routes/unbond/UnbondForm.tsx | 34 --------- tauri-wallet/src/routes/unbond/index.tsx | 59 +++++++++++++++- tauri-wallet/src/types/global.ts | 4 +- tauri-wallet/src/utils/index.ts | 1 - 12 files changed, 214 insertions(+), 88 deletions(-) create mode 100644 tauri-wallet/src/hooks/useCheckOwnership.ts delete mode 100644 tauri-wallet/src/routes/unbond/UnbondForm.tsx diff --git a/tauri-wallet/src/components/NodeTypeSelector.tsx b/tauri-wallet/src/components/NodeTypeSelector.tsx index db235fe78e..b949eb00d3 100644 --- a/tauri-wallet/src/components/NodeTypeSelector.tsx +++ b/tauri-wallet/src/components/NodeTypeSelector.tsx @@ -9,9 +9,11 @@ import React from 'react' import { EnumNodeType } from '../types/global' export const NodeTypeSelector = ({ + disabled, nodeType, setNodeType, }: { + disabled: boolean nodeType: EnumNodeType setNodeType: (nodeType: EnumNodeType) => void }) => { @@ -32,11 +34,13 @@ export const NodeTypeSelector = ({ value={EnumNodeType.mixnode} control={} label="Mixnode" + disabled={disabled} /> } label="Gateway" + disabled={disabled} /> diff --git a/tauri-wallet/src/context/main.tsx b/tauri-wallet/src/context/main.tsx index 9e8dfe7482..da14162777 100644 --- a/tauri-wallet/src/context/main.tsx +++ b/tauri-wallet/src/context/main.tsx @@ -1,6 +1,6 @@ import React, { createContext, useEffect, useState } from 'react' import { useHistory } from 'react-router-dom' -import { Coin, TClientDetails, TSignInWithMnemonic } from '../types' +import { TClientDetails, TSignInWithMnemonic } from '../types' import { TUseGetBalance, useGetBalance } from '../hooks/useGetBalance' export const ADMIN_ADDRESS = 'punk1h3w4nj7kny5dfyjw2le4vm74z03v9vd4dstpu0' diff --git a/tauri-wallet/src/hooks/useCheckOwnership.ts b/tauri-wallet/src/hooks/useCheckOwnership.ts new file mode 100644 index 0000000000..6022fd0a4b --- /dev/null +++ b/tauri-wallet/src/hooks/useCheckOwnership.ts @@ -0,0 +1,39 @@ +import { useEffect, useState } from 'react' +import { checkGatewayOwnership, checkMixnodeOwnership } from '../requests' +import { EnumNodeType, TNodeOwnership } from '../types' + +export const useCheckOwnership = () => { + const [ownership, setOwnership] = useState({ + hasOwnership: false, + nodeType: undefined, + }) + const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState() + + const checkOwnership = async () => { + const status = {} as TNodeOwnership + + setIsLoading(true) + + try { + const ownsMixnode = await checkMixnodeOwnership() + const ownsGateway = await checkGatewayOwnership() + + if (ownsMixnode) { + status.hasOwnership = true + status.nodeType = EnumNodeType.mixnode + } + + if (ownsGateway) { + status.hasOwnership = true + status.nodeType = EnumNodeType.gateway + } + + setOwnership(status) + } catch (e) { + setError(e as string) + } + } + + return { isLoading, error, ownership, checkOwnership } +} diff --git a/tauri-wallet/src/hooks/useGetBalance.tsx b/tauri-wallet/src/hooks/useGetBalance.tsx index b60e1bb4f0..013e9bd550 100644 --- a/tauri-wallet/src/hooks/useGetBalance.tsx +++ b/tauri-wallet/src/hooks/useGetBalance.tsx @@ -11,17 +11,17 @@ export type TUseGetBalance = { export const useGetBalance = (): TUseGetBalance => { const [balance, setBalance] = useState() - const [error, setEror] = useState() + const [error, setErorr] = useState() const [isLoading, setIsLoading] = useState(false) const fetchBalance = () => { setIsLoading(true) - setEror(undefined) + setErorr(undefined) invoke('get_balance') .then((balance) => { setBalance(balance as Balance) }) - .catch((e) => setEror(e)) + .catch((e) => setErorr(e)) setTimeout(() => { setIsLoading(false) }, 1000) diff --git a/tauri-wallet/src/requests/index.ts b/tauri-wallet/src/requests/index.ts index db63db1b45..8f08803b16 100644 --- a/tauri-wallet/src/requests/index.ts +++ b/tauri-wallet/src/requests/index.ts @@ -3,6 +3,8 @@ import { Coin, DelegationResult, EnumNodeType, + Gateway, + MixNode, Operation, TauriTxResult, TCreateAccount, @@ -51,3 +53,21 @@ export const send = async (args: { address: string memo: string }): Promise => await invoke('send', args) +export const checkMixnodeOwnership = async (): Promise => + await invoke('owns_mixnode') + +export const checkGatewayOwnership = async (): Promise => + await invoke('owns_gateway') + +export const bond = async ({ + type, + data, + amount, +}: { + type: EnumNodeType + data: MixNode | Gateway + amount: Coin +}): Promise => await invoke(`bond_${type}`, { [type]: data, bond: amount }) + +export const unbond = async (type: EnumNodeType) => + await invoke(`unbond_${type}`) diff --git a/tauri-wallet/src/routes/bond/BondForm.tsx b/tauri-wallet/src/routes/bond/BondForm.tsx index 21e89505fa..c0ed3cab81 100644 --- a/tauri-wallet/src/routes/bond/BondForm.tsx +++ b/tauri-wallet/src/routes/bond/BondForm.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useContext } from 'react' import { Button, Checkbox, @@ -11,14 +11,15 @@ import { Theme, } from '@material-ui/core' import { useTheme } from '@material-ui/styles' -import { useForm } from 'react-hook-form' +import { Alert } from '@material-ui/lab' import { yupResolver } from '@hookform/resolvers/yup' +import { useForm } from 'react-hook-form' import { EnumNodeType } from '../../types/global' import { NodeTypeSelector } from '../../components/NodeTypeSelector' +import { bond, majorToMinor } from '../../requests' import { validationSchema } from './validationSchema' import { Coin, Gateway, MixNode } from '../../types' -import { invoke } from '@tauri-apps/api' -import { Alert } from '@material-ui/lab' +import { ClientContext } from '../../context/main' type TBondFormFields = { withAdvancedOptions: boolean @@ -57,29 +58,27 @@ const formatData = (data: TBondFormFields) => { host: data.host, version: data.version, mix_port: data.mixPort, - amount: data.amount, - nodeType: data.nodeType, } if (data.nodeType === EnumNodeType.mixnode) { payload.verloc_port = data.verlocPort payload.http_api_port = data.httpApiPort - return payload as MixNode & { amount: number; nodeType: EnumNodeType } - } - - if (data.nodeType == EnumNodeType.gateway) { + return payload as MixNode + } else { payload.clients_port = data.clientsPort payload.location = data.location - return payload as Gateway & { amount: number; nodeType: EnumNodeType } + return payload as Gateway } } export const BondForm = ({ + disabled, fees, onError, onSuccess, }: { - fees: { [key in EnumNodeType]: Coin } + disabled: boolean + fees?: { [key in EnumNodeType]: Coin } onError: (message?: string) => void onSuccess: (message?: string) => void }) => { @@ -94,6 +93,8 @@ export const BondForm = ({ defaultValues, }) + const { getBalance } = useContext(ClientContext) + const watchNodeType = watch('nodeType', defaultValues.nodeType) const watchAdvancedOptions = watch( 'withAdvancedOptions', @@ -102,12 +103,12 @@ export const BondForm = ({ const onSubmit = async (data: TBondFormFields) => { const formattedData = formatData(data) - await invoke(`bond_${data.nodeType}`, { - [data.nodeType]: formattedData, - bond: { amount: formattedData?.amount, denom: 'Major' }, - }) - .then((res: any) => { - onSuccess(res) + const amount = await majorToMinor(data.amount) + + await bond({ type: data.nodeType, data: formattedData, amount }) + .then(() => { + getBalance.fetchBalance() + onSuccess(`Successfully bonded to ${data.identityKey}`) }) .catch((e) => { onError(e) @@ -129,17 +130,20 @@ export const BondForm = ({ if (nodeType === EnumNodeType.mixnode) setValue('location', undefined) }} + disabled={disabled} /> - - - {`A fee of ${ - watchNodeType === EnumNodeType.mixnode - ? fees.mixnode.amount - : fees.gateway.amount - } PUNK will apply to this transaction`} - - + {fees && ( + + + {`A fee of ${ + watchNodeType === EnumNodeType.mixnode + ? fees.mixnode.amount + : fees.gateway.amount + } PUNK will apply to this transaction`} + + + )} @@ -165,6 +170,7 @@ export const BondForm = ({ error={!!errors.sphinxKey} helperText={errors.sphinxKey?.message} fullWidth + disabled={disabled} /> @@ -183,6 +189,7 @@ export const BondForm = ({ punks ), }} + disabled={disabled} /> @@ -197,6 +204,7 @@ export const BondForm = ({ fullWidth error={!!errors.host} helperText={errors.host?.message} + disabled={disabled} /> @@ -213,6 +221,7 @@ export const BondForm = ({ fullWidth error={!!errors.location} helperText={errors.location?.message} + disabled={disabled} /> )} @@ -228,6 +237,7 @@ export const BondForm = ({ fullWidth error={!!errors.version} helperText={errors.version?.message} + disabled={disabled} /> @@ -275,6 +285,7 @@ export const BondForm = ({ helperText={ errors.mixPort?.message && 'A valid port value is required' } + disabled={disabled} /> {watchNodeType === EnumNodeType.mixnode ? ( @@ -292,6 +303,7 @@ export const BondForm = ({ errors.verlocPort?.message && 'A valid port value is required' } + disabled={disabled} /> @@ -308,6 +320,7 @@ export const BondForm = ({ errors.httpApiPort?.message && 'A valid port value is required' } + disabled={disabled} /> @@ -325,6 +338,7 @@ export const BondForm = ({ errors.clientsPort?.message && 'A valid port value is required' } + disabled={disabled} /> )} @@ -343,7 +357,7 @@ export const BondForm = ({ }} > + } + style={{ margin: theme.spacing(2) }} + > + {`Looks like you already have a ${ownership.nodeType} bonded.`} + + )} {status === EnumRequestStatus.loading && ( { )} {status === EnumRequestStatus.initial && ( { setMessage(e) setStatus(EnumRequestStatus.error) @@ -59,6 +84,7 @@ export const Bond = () => { setMessage(message) setStatus(EnumRequestStatus.success) }} + disabled={ownership?.hasOwnership} /> )} {(status === EnumRequestStatus.error || @@ -88,6 +114,7 @@ export const Bond = () => { - - - ) -} diff --git a/tauri-wallet/src/routes/unbond/index.tsx b/tauri-wallet/src/routes/unbond/index.tsx index ff768ab63e..9ae5ed6f01 100644 --- a/tauri-wallet/src/routes/unbond/index.tsx +++ b/tauri-wallet/src/routes/unbond/index.tsx @@ -1,13 +1,68 @@ -import React from 'react' +import React, { useContext, useEffect, useState } from 'react' import { NymCard } from '../../components' import { UnbondForm } from './UnbondForm' import { Layout } from '../../layouts' +import { useCheckOwnership } from '../../hooks/useCheckOwnership' +import { Alert } from '@material-ui/lab' +import { Box, Button, CircularProgress, Theme } from '@material-ui/core' +import { ClientContext } from '../../context/main' +import { unbond } from '../../requests' +import { useTheme } from '@material-ui/styles' export const Unbond = () => { + const [isLoading, setIsLoading] = useState(false) + const { checkOwnership, ownership } = useCheckOwnership() + const { getBalance } = useContext(ClientContext) + + const theme: Theme = useTheme() + + useEffect(() => { + const initialiseForm = async () => { + await checkOwnership() + } + initialiseForm() + }, [ownership.hasOwnership, checkOwnership]) + return ( - + {ownership?.hasOwnership && ( + { + setIsLoading(true) + await unbond(ownership.nodeType!) + getBalance.fetchBalance() + setIsLoading(false) + }} + > + Unbond + + } + style={{ margin: theme.spacing(2) }} + > + {`Looks like you already have a ${ownership.nodeType} bonded.`} + + )} + {!ownership.hasOwnership && ( + + You don't currently have a bonded node + + )} + {isLoading && ( + + + + )} ) diff --git a/tauri-wallet/src/types/global.ts b/tauri-wallet/src/types/global.ts index cfb41568f2..672f1629d6 100644 --- a/tauri-wallet/src/types/global.ts +++ b/tauri-wallet/src/types/global.ts @@ -6,8 +6,8 @@ export enum EnumNodeType { } export type TNodeOwnership = { - ownsMixnode: boolean - ownsGateway: boolean + hasOwnership: boolean + nodeType?: EnumNodeType } export type TClientDetails = { diff --git a/tauri-wallet/src/utils/index.ts b/tauri-wallet/src/utils/index.ts index f64530eee5..fe47b62c3e 100644 --- a/tauri-wallet/src/utils/index.ts +++ b/tauri-wallet/src/utils/index.ts @@ -75,7 +75,6 @@ export const validateVersion = (version: string): boolean => { const validVersion = valid(version) return validVersion !== null && minorVersion >= 11 } catch (e) { - console.log(e) return false } }