diff --git a/src/assets/skip-white.svg b/src/assets/skip-white.svg deleted file mode 100644 index a2121d51..00000000 --- a/src/assets/skip-white.svg +++ /dev/null @@ -1,18 +0,0 @@ - - \ No newline at end of file diff --git a/src/assets/skip.svg b/src/assets/skip.svg deleted file mode 100644 index 897e2305..00000000 --- a/src/assets/skip.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/src/components/App.js b/src/components/App.js index 396fbbf1..f202ae74 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -5,7 +5,7 @@ import _ from 'lodash' import AlertMessage from './AlertMessage' import NetworkSelect from './NetworkSelect' import Delegations from './Delegations'; -import Coins from './Coins' +import Coin from './Coin' import About from './About' import { @@ -21,7 +21,7 @@ import { DropletFill, DropletHalf, CashCoin, - Coin, + Coin as CoinIcon, EnvelopePaper, Stars, WrenchAdjustableCircle, @@ -298,7 +298,8 @@ class App extends React.Component { return this.restClient().getBalance(this.state.address) .then( (balances) => { - const balance = balances?.find( + balances = _.compact(balances || []) + const balance = balances.find( (element) => element.denom === this.props.network.denom ) || { denom: this.props.network.denom, amount: 0 }; this.setState({ @@ -585,7 +586,7 @@ class App extends React.Component { <>
Grant remaining:
Grant remaining:
- Enabling REStake will authorize the validator to send Delegate transactions on your behalf using Authz.
+ Enabling REStake will authorize the validator to send Delegate transactions on your behalf using Authz.
They will only be authorized to delegate to their own validator. You can revoke the authorization at any time and everything is open source.
diff --git a/src/components/Grants.js b/src/components/Grants.js
index 83825432..00a75dbc 100644
--- a/src/components/Grants.js
+++ b/src/components/Grants.js
@@ -13,7 +13,7 @@ import { XCircle } from "react-bootstrap-icons";
import AlertMessage from './AlertMessage';
import RevokeGrant from './RevokeGrant';
-import Coins from './Coins';
+import Coin from './Coin';
import GrantModal from './GrantModal';
import Favourite from './Favourite';
import Address from './Address'
@@ -101,7 +101,7 @@ function Grants(props) {
const restrictionList = grant.authorization.allow_list || grant.authorization.deny_list
return (
- Maximum: {maxTokens ?
+ Maximum: {maxTokens ?
{restrictionType}: {restrictionList.address.map(address => {
const validator = validators[address]
return address ?
diff --git a/src/components/ProposalMessages.js b/src/components/ProposalMessages.js
index 888b2d6f..00f70481 100644
--- a/src/components/ProposalMessages.js
+++ b/src/components/ProposalMessages.js
@@ -5,9 +5,9 @@ import {
import moment from 'moment'
import _ from 'lodash'
import Moment from 'react-moment';
-import Coins from './Coins';
-import { omit } from '../utils/Helpers.mjs';
import truncateMiddle from 'truncate-middle';
+import { omit } from '../utils/Helpers.mjs';
+import Coins from './Coins';
function ProposalMessages(props) {
const { proposal, network } = props
@@ -46,13 +46,14 @@ function ProposalMessages(props) {
)
}
}
- case '/cosmos.distribution.v1beta1.CommunityPoolSpendProposal':
+ case [
+ '/cosmos.distribution.v1beta1.CommunityPoolSpendProposal',
+ '/cosmos.distribution.v1beta1.MsgCommunityPoolSpend'
+ ].find(type => type === message['@type']):
return {
...data,
amount: () => {
- return data.amount?.map((coin, index) => {
- return Total deposit
- {proposal.total_deposit.map(coins => {
- return
{operator.moniker} will be able to carry out the following transactions on your behalf:
-Delegate - allowed to delegate {maxTokensDenom() ? <>a maximum of
Delegate - allowed to delegate {maxTokensDenom() ? <>a maximum of
This grant will expire automatically on {state.expiryDateValue} and you can revoke it at any time.
{operator.moniker} will only auto-compound their accrued rewards and tries not to touch your balance.
They will pay the transaction fees for you.
REStakes {operator.runTimesString()}
Minimum reward is{" "}
-
{tooltipContent}
diff --git a/src/components/SendModal.js b/src/components/SendModal.js index f7d36725..09de7f5a 100644 --- a/src/components/SendModal.js +++ b/src/components/SendModal.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import _ from 'lodash' -import { pow, multiply, divide, subtract, bignumber } from 'mathjs' +import { pow, multiply, divide, numeric, bignumber, format } from 'mathjs' import { MsgSend } from "../messages/MsgSend.mjs"; @@ -8,20 +8,28 @@ import { Modal, Button, Form, + Dropdown } from 'react-bootstrap' import AlertMessage from './AlertMessage'; -import { coin, execableMessage, truncateAddress } from '../utils/Helpers.mjs'; -import Coins from './Coins'; +import { coin, execableMessage, sortCoins, truncateAddress } from '../utils/Helpers.mjs'; +import Coin from './Coin'; function SendModal(props) { - const { show, network, address, wallet } = props + const { show, network, address, wallet, balances } = props const [loading, setLoading] = useState(false); const [error, setError] = useState() - const [state, setState] = useState({recipientValue: '', customRecipientValue: '', memoValue: ''}); - - const denom = network && network.symbol - const step = 1 / pow(10, network?.decimals || 6) + const [state, setState] = useState({recipientValue: '', customRecipientValue: '', amountValue: '', denomValue: '', memoValue: ''}); + + const asset = state.denomValue && network.assetForDenom(state.denomValue) + const balance = asset && balances?.find(el => el.denom === asset.denom) + const sortedBalances = sortCoins(balances, network) + const assets = _.compact(sortedBalances?.map(el => network.assetForDenom(el.denom)) || []) + const step = 1 / pow(10, asset?.decimals || 6) + let value + if(state.amountValue && asset && asset.prices?.coingecko?.usd){ + value = numeric(multiply(state.amountValue, asset.prices.coingecko.usd), 'number') + } useEffect(() => { setState({ @@ -29,6 +37,7 @@ function SendModal(props) { recipientValue: '', customRecipientValue: '', amountValue: '', + denomValue: network.denom, memoValue: '', }) setError(null) @@ -38,6 +47,10 @@ function SendModal(props) { setState({ ...state, [e.target.name]: e.target.value }); } + function handleDenomValueChange(denom) { + setState({ ...state, amountValue: '', denomValue: denom }); + } + function showLoading(isLoading) { setLoading(isLoading) props.setLoading && props.setLoading(isLoading) @@ -63,6 +76,7 @@ function SendModal(props) { recipientValue: '', customRecipientValue: '', amountValue: '', + denomValue: network.denom, memoValue: '', }) props.onSend(recipient(), coinValue); @@ -88,19 +102,9 @@ function SendModal(props) { } async function setAvailableAmount(){ - setError(null) - const decimals = pow(10, network.decimals) - const coinValue = coin(multiply(props.balance.amount, 0.95), network.denom) - const message = buildSendMsg(address, recipient(), [coinValue]) - wallet.simulate([message]).then(gas => { - const gasPrice = wallet.getFee(gas).amount[0].amount - const amount = divide(subtract(bignumber(props.balance.amount), gasPrice), decimals) - - setState({...state, amountValue: amount > 0 ? amount : 0}) - }, error => { - console.log(error) - setError(error.message) - }) + const decimals = pow(10, asset.decimals) + const amount = divide(bignumber(balance.amount), decimals) + setState({...state, amountValue: format(amount, {notation: 'fixed'})}) } function recipient(){ @@ -110,16 +114,16 @@ function SendModal(props) { function coinAmount(){ if(!state.amountValue) return null - const decimals = pow(10, network.decimals) + const decimals = pow(10, asset.decimals) const denomAmount = multiply(state.amountValue, decimals) if(denomAmount > 0){ - return coin(denomAmount, network.denom) + return coin(denomAmount, asset.denom) } } function valid(){ if(!state.recipientValue) return true - return validRecipient() && coinAmount() && wallet?.hasPermission(address, 'Send') + return validRecipient() && coinAmount() && validBalance() && wallet?.hasPermission(address, 'Send') } function validAmount(){ @@ -135,6 +139,15 @@ function SendModal(props) { return !network.prefix || value.startsWith(network.prefix) } + function validBalance(){ + if(!state.amountValue) return true + + const coinValue = coinAmount() + if(!coinValue) return false + + return bignumber(coinValue.amount).lte(balance.amount) + } + function favourites(){ return props.favouriteAddresses.filter(el => el.address !== props.address) } @@ -151,61 +164,85 @@ function SendModal(props) { {error} } -- {!loading - ? ( - - ) - :
+ {!loading + ? ( + - } -
- > - )} - + ) + : + } + + > + )} > diff --git a/src/components/ValidatorCalculator.js b/src/components/ValidatorCalculator.js index 0e4d1d14..32b91cb5 100644 --- a/src/components/ValidatorCalculator.js +++ b/src/components/ValidatorCalculator.js @@ -11,7 +11,7 @@ import { import { QuestionCircle } from "react-bootstrap-icons"; import TooltipIcon from './TooltipIcon' -import Coins from './Coins'; +import Coin from './Coin'; function ValidatorCalculator(props) { const { validator, operator, network, delegation } = props @@ -229,11 +229,14 @@ function ValidatorCalculator(props) { {amountDenom === network.symbol ? ( ${usdAmount().toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })} ) : ( -{validator.description?.details}
- {!!network.chain.services?.skip && !!validator.services?.skip && ( - <> - -Status | -
- {validator.services.skip.active ? (
- <>
- Active
- {validator.services.skip.front_running_protection && <> Front-running protected>} - > - ) : Inactive} - |
-
Network profit | -
- {100 - validator.services.skip.val_payment_percentage}% - |
-
Validator profit | -
- {validator.services.skip.val_payment_percentage}% - |
-