diff --git a/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ActionMenu.tsx b/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ActionMenu.tsx index f5fdbd7d5d..3a3cc75d16 100644 --- a/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ActionMenu.tsx +++ b/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ActionMenu.tsx @@ -27,6 +27,7 @@ import { useAccountsCreateFreeTestCoins } from '../../../api/hooks/useAccounts'; import ClaimBurn from './ClaimBurn'; import useAccountStore from '../../../store/accountStore'; import SendMoney from './SendMoney'; +import ClaimFees from './ClaimFees'; function ActionMenu() { const { mutate } = useAccountsCreateFreeTestCoins(); @@ -49,7 +50,8 @@ function ActionMenu() { marginBottom: theme.spacing(2), }} > - + + diff --git a/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ClaimFees.tsx b/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ClaimFees.tsx new file mode 100644 index 0000000000..dee400c7b7 --- /dev/null +++ b/applications/tari_dan_wallet_web_ui/src/routes/AssetVault/Components/ClaimFees.tsx @@ -0,0 +1,225 @@ +// Copyright 2022. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import { useState } from "react"; +import { Form } from "react-router-dom"; +import Button from "@mui/material/Button"; +import CheckBox from "@mui/material/Checkbox"; +import TextField from "@mui/material/TextField"; +import Dialog from "@mui/material/Dialog"; +import DialogContent from "@mui/material/DialogContent"; +import DialogTitle from "@mui/material/DialogTitle"; +import FormControlLabel from "@mui/material/FormControlLabel"; +import Box from "@mui/material/Box"; +import { useAccountsList, useAccountsTransfer } from "../../../api/hooks/useAccounts"; +import { useTheme } from "@mui/material/styles"; +import useAccountStore from "../../../store/accountStore"; +import { FormControl, InputLabel, MenuItem, Select, SelectChangeEvent } from "@mui/material"; +import { claimFees } from "../../../utils/json_rpc"; +import { useKeysList } from "../../../api/hooks/useKeys"; + +export default function ClaimFees() { + const [open, setOpen] = useState(false); + const [disabled, setDisabled] = useState(false); + const [estimatedFee, setEstimatedFee] = useState(0); + const [claimFeesFormState, setClaimFeesFormState] = useState({ + account: "", + fee: "", + validatorNodePublicKey: "", + epoch: "", + key: "", + newAccount: false, + disabled: false, + }); + + + const { data: dataAccountsList } = useAccountsList(0, 10); + const { data: dataKeysList } = useKeysList(); + const { setPopup } = useAccountStore(); + + const theme = useTheme(); + + const isFormFilled = () => { + if (claimFeesFormState.validatorNodePublicKey.length !== 64) { + return false; + } + return claimFeesFormState.account !== "" && claimFeesFormState.validatorNodePublicKey !== "" && claimFeesFormState.epoch !== ""; + }; + + const is_filled = isFormFilled(); + + const onClaimFeesKeyChange = (e: SelectChangeEvent) => { + let key = e.target.value; + let key_index = dataKeysList.keys.indexOf(key); + let account = claimFeesFormState.account; + let selected_account = dataAccountsList.accounts.find((account: any) => account.account.key_index === key_index); + let new_account_name; + if (selected_account !== undefined) { + account = selected_account.account.name; + new_account_name = false; + } else { + if (claimFeesFormState.newAccount === false) { + account = ""; + } + new_account_name = true; + } + setClaimFeesFormState({ + ...claimFeesFormState, + "key": key, + "account": account, + "newAccount": new_account_name, + }); + }; + + const onEpochChange = (e: React.ChangeEvent) => { + if (/^[0-9]*$/.test(e.target.value)) { + setClaimFeesFormState({ + ...claimFeesFormState, + [e.target.name]: e.target.value, + }); + } + } + + const onClaimBurnAccountNameChange = (e: React.ChangeEvent) => { + setClaimFeesFormState({ + ...claimFeesFormState, + [e.target.name]: e.target.value, + }); + } + + const onPublicKeyChange = (e: React.ChangeEvent) => { + if (/^[0-9a-fA-F]*$/.test(e.target.value)) { + setClaimFeesFormState({ + ...claimFeesFormState, + [e.target.name]: e.target.value, + }); + } + setEstimatedFee(0); + }; + + const onClaim = async () => { + if (claimFeesFormState.account) { + setDisabled(true); + claimFees(claimFeesFormState.account, 3000, claimFeesFormState.validatorNodePublicKey, parseInt(claimFeesFormState.epoch)).then((resp) => { + console.log(resp); + }).catch((e) => { + console.error(e); + }).finally(() => { + setDisabled(false); + }); + }; + } + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + const formattedKey = (key: any[]) => { + let account = dataAccountsList.accounts.find((account: any) => account.account.key_index === +key[0]) + if (account === undefined) { + return null + return
{key[0]} {key[1]}
+ } + return
{key[0]} {key[1]}

Account {account.account.name}
+ } + + return ( +
+ + + Claim Fees + +
+ + Key + + + + + + + + + + + + +
+
+
+ ); +} diff --git a/applications/tari_dan_wallet_web_ui/src/utils/json_rpc.tsx b/applications/tari_dan_wallet_web_ui/src/utils/json_rpc.tsx index 6413c8a43c..3257fee884 100644 --- a/applications/tari_dan_wallet_web_ui/src/utils/json_rpc.tsx +++ b/applications/tari_dan_wallet_web_ui/src/utils/json_rpc.tsx @@ -34,13 +34,13 @@ async function internalJsonRpc(method: string, token: any = null, params: any = id = json_id; json_id += 1; }); - let address = "http://localhost:9000"; - try { - address = await (await fetch('/json_rpc_address')).text(); - if (!address.startsWith("http")) { - address = "http://" + address; - } - } catch { } + let address = "http://127.0.0.1:18016"; + // try { + // address = await (await fetch('/json_rpc_address')).text(); + // if (!address.startsWith("http")) { + // address = "http://" + address; + // } + // } catch { } let headers: { [key: string]: string } = { "Content-Type": "application/json", }; @@ -185,3 +185,7 @@ export const accountNFTsList = (offset: number, limit: number) => jsonRpc("nfts. // settings export const getSettings = () => jsonRpc("settings.get", []); export const setSettings = (settings: any) => jsonRpc("settings.set", settings); + +// validators +export const getFeeSummary = (validatorPublicKey: string, minEpoch: number, maxEpoch: number) => jsonRpc("validators.get_fee_summary", [validatorPublicKey, minEpoch, maxEpoch]); +export const claimFees = (account: string, maxFee: number, validatorPublicKey: string, epoch: number) => jsonRpc("validators.claim_fees", [account, maxFee, validatorPublicKey, epoch]);