JS and CSS refactorings, fixes, and improvements

staking
Vadim 5 years ago committed by Victor Baranov
parent fbcf251f74
commit 187a8dd37d
  1. 5
      apps/block_scout_web/assets/css/_mixins.scss
  2. 8
      apps/block_scout_web/assets/css/components/_form.scss
  3. 9
      apps/block_scout_web/assets/css/theme/_dai_variables.scss
  4. 12
      apps/block_scout_web/assets/css/theme/_dark-theme.scss
  5. 1
      apps/block_scout_web/assets/js/pages/stakes.js
  6. 51
      apps/block_scout_web/assets/js/pages/stakes/claim_reward.js
  7. 15
      apps/block_scout_web/assets/js/pages/stakes/make_stake.js
  8. 19
      apps/block_scout_web/assets/js/pages/stakes/remove_pool.js
  9. 110
      apps/block_scout_web/assets/js/pages/stakes/utils.js

@ -172,8 +172,9 @@
&[disabled] {
&,
&:hover {
background-color: $bg-color;
border-color: $text-color;
background-color: $bg-color!important;
border-color: $primary!important;
color: $primary!important;
cursor: default;
opacity: 0.5;
}

@ -92,6 +92,14 @@ $form-control-border-color-active: $primary !default;
color: white;
background: #FF7884;
border-radius: 0 0 2px 2px;
.link-helptip {
border-bottom-width: 1px;
border-bottom-style: dotted;
color: inherit;
cursor: help;
text-decoration: none;
}
}
}

@ -105,6 +105,15 @@ $dark-tertiary: #5a77ff;
background-color: transparent!important;
border-color: $dark-tertiary!important;
color: $dark-tertiary!important;
&[disabled] {
&,
&:hover {
background-color: transparent!important;
border-color: $dark-tertiary!important;
color: $dark-tertiary!important;
}
}
}
.dark-theme-applied .btn-line:hover {

@ -296,6 +296,14 @@ $dark-stakes-banned-background: #3e314c;
color: $labels-dark;
}
.stakes-table-body {
.refresh-informer {
a {
color: inherit;
}
}
}
.stakes-td {
border-bottom-color: darken($labels-dark, 30);
}
@ -554,6 +562,10 @@ $dark-stakes-banned-background: #3e314c;
color: #fff;
transition: border-color 0.15s ease-in-out;
&[readonly] {
background-color: $dark-light!important;
}
&::placeholder {
color: $labels-dark;
}

@ -29,6 +29,7 @@ export const initialState = {
network: null,
refreshBlockNumber: 0, // last page refresh block number
refreshInterval: null,
refreshPageFunc: refreshPageWrapper,
stakingAllowed: false,
stakingTokenDefined: false,
stakingContract: null,

@ -9,7 +9,7 @@ import {
unlockModal
} from '../../lib/modals'
import { displayInputError, hideInputError } from '../../lib/validation'
import { isSupportedNetwork } from './utils'
import { isSupportedNetwork, makeContractCall } from './utils'
let status = 'modalClosed'
@ -230,53 +230,20 @@ function onPoolsFound ($modal, $modalBody, channel, store) {
const gasLimit = parseInt($('#tx-gas-limit', $modalBody).text().replace(/~/g, '').trim(), 10)
const state = store.getState()
const stakingContract = state.stakingContract
const from = state.account
const web3 = state.web3
if (isNaN(gasLimit)) {
claimFinished('Invalid gas limit. Please, contact support.')
} else if (!stakingContract) {
claimFinished('Staking contract is undefined. Please, contact support.')
} else if (!from) {
claimFinished('Your MetaMask account is undefined. Please, contact support.')
} else if (!web3) {
claimFinished('Web3 is undefined. Please, contact support.')
} else if (!poolStakingAddress) {
claimFinished('Pool staking address is undefined. Please, contact support.')
} else {
stakingContract.methods.claimReward(epochs, poolStakingAddress).send({
from,
gasPrice: web3.utils.toWei('1', 'gwei'),
gas: Math.ceil(gasLimit * 1.2) // +20% reserve to ensure enough gas
}, async function (error, txHash) {
if (error) {
claimFinished(error.message)
} else {
try {
let tx
let currentBlockNumber
const maxWaitBlocks = 6
const startBlockNumber = (await web3.eth.getBlockNumber()) - 0
const finishBlockNumber = startBlockNumber + maxWaitBlocks
do {
await sleep(5) // seconds
tx = await web3.eth.getTransactionReceipt(txHash)
currentBlockNumber = await web3.eth.getBlockNumber()
} while (tx === null && currentBlockNumber <= finishBlockNumber)
if (tx) {
if (tx.status === true || tx.status === '0x1') {
claimFinished()
} else {
claimFinished('Transaction reverted')
}
} else {
claimFinished(`Your transaction was not mined in ${maxWaitBlocks} blocks. Please, try again with the increased gas price or fixed nonce (use Reset Account feature of MetaMask).`)
}
} catch (e) {
claimFinished(e.message)
}
}
})
makeContractCall(
stakingContract.methods.claimReward(epochs, poolStakingAddress),
store,
gasLimit,
claimFinished
)
}
}
function claimFinished (error) {
@ -303,10 +270,6 @@ function lockUI (lock, $modal, $button, $poolsDropdown, $epochChoiceRadio, $spec
$specifiedEpochsText.prop('disabled', lock)
}
function sleep (seconds) {
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
}
function showButton (type, $modalBody, calculations) {
const $recalculateButton = $('button.recalculate', $modalBody)
const $submitButton = $('button.submit', $modalBody)

@ -2,19 +2,22 @@ import $ from 'jquery'
import { BigNumber } from 'bignumber.js'
import { openErrorModal, openModal, openWarningModal, lockModal } from '../../lib/modals'
import { setupValidation } from '../../lib/validation'
import { makeContractCall, setupChart, isSupportedNetwork } from './utils'
import { makeContractCall, setupChart, isSupportedNetwork, isStakingAllowed } from './utils'
export function openMakeStakeModal (event, store) {
if (!store.getState().account) {
const state = store.getState()
if (!state.account) {
openWarningModal('Unauthorized', 'You haven\'t approved the reading of account list from your MetaMask or MetaMask is not installed.')
return
}
if (!isSupportedNetwork(store)) return
if (!isStakingAllowed(state)) return
const address = $(event.target).closest('[data-address]').data('address') || store.getState().account
store.getState().channel
state.channel
.push('render_make_stake', { address })
.receive('ok', msg => {
const $modal = $(msg.html)
@ -47,8 +50,6 @@ export function openMakeStakeModal (event, store) {
}
async function makeStake ($modal, address, store, msg) {
lockModal($modal)
const state = store.getState()
const stakingContract = state.stakingContract
const validatorSetContract = state.validatorSetContract
@ -56,6 +57,10 @@ async function makeStake ($modal, address, store, msg) {
const stake = new BigNumber($modal.find('[delegator-stake]').val().replace(',', '.').trim()).shiftedBy(decimals).integerValue()
if (!isSupportedNetwork(store)) return
if (!isStakingAllowed(state)) return
lockModal($modal)
let miningAddress = msg.mining_address
if (!miningAddress || miningAddress === '0x0000000000000000000000000000000000000000') {
miningAddress = await validatorSetContract.methods.miningByStakingAddress(address).call()

@ -1,4 +1,4 @@
import { openQuestionModal } from '../../lib/modals'
import { openErrorModal, openQuestionModal } from '../../lib/modals'
import { makeContractCall, isSupportedNetwork } from './utils'
export function openRemovePoolModal (store) {
@ -7,6 +7,19 @@ export function openRemovePoolModal (store) {
}
async function removePool (store) {
const contract = store.getState().stakingContract
makeContractCall(contract.methods.removeMyPool(), store)
const state = store.getState()
const call = state.stakingContract.methods.removeMyPool()
let gasLimit
try {
gasLimit = await call.estimateGas({
from: state.account,
gasPrice: 1000000000
})
} catch (err) {
openErrorModal('Error', 'Currently you cannot remove your pool. Please try again during the next epoch.')
return
}
makeContractCall(call, store, gasLimit)
}

@ -1,55 +1,79 @@
import $ from 'jquery'
import Chart from 'chart.js'
import { refreshPage } from '../../lib/async_listing_load'
import { openErrorModal, openSuccessModal, openWarningModal } from '../../lib/modals'
export async function makeContractCall (call, store) {
let gas, timeout
let resultShown = false
const account = store.getState().account
export async function makeContractCall (call, store, gasLimit, callbackFunc) {
const state = store.getState()
const from = state.account
const web3 = state.web3
try {
gas = await call.estimateGas({
from: account,
gasPrice: 1000000000
})
} catch (err) {
openErrorModal('Error', 'Your transaction cannot be mined at the moment. Please, try again in a few blocks.')
return
if (!callbackFunc) {
callbackFunc = function (errorMessage) {
if (!errorMessage) {
state.refreshPageFunc(store)
openSuccessModal('Success', 'Transaction is confirmed.')
} else {
openErrorModal('Error', errorMessage)
}
}
}
try {
await call.send({
from: account,
gas: Math.ceil(gas * 1.2),
gasPrice: 1000000000
}).once('transactionHash', (hash) => {
timeout = setTimeout(() => {
if (!resultShown) {
openErrorModal('Error', 'Your transaction cannot be mined at the moment. Please, try again with the increased gas price or fixed nonce (use Reset Account feature of MetaMask).')
resultShown = true
}
}, 30000)
})
if (!from) {
return callbackFunc('Your MetaMask account is undefined. Please, contact support.')
} else if (!web3) {
return callbackFunc('Web3 is undefined. Please, contact support.')
}
clearTimeout(timeout)
refreshPage(store)
const gasPrice = web3.utils.toWei('1', 'gwei')
if (!resultShown) {
openSuccessModal('Success', 'Transaction is confirmed.')
resultShown = true
}
} catch (err) {
clearTimeout(timeout)
let errorMessage = 'Your MetaMask transaction was not processed, please try again in a few minutes.'
if (err.message) {
const detailsMessage = err.message.replace(/["]/g, '&quot;')
console.log(detailsMessage)
const detailsHTML = ` <a href="javascript:void(0);" data-boundary="window" data-container="body" data-html="false" data-placement="top" data-toggle="tooltip" title="${detailsMessage}" data-original-title="${detailsMessage}" class="link-helptip">Details</a>`
errorMessage = errorMessage + detailsHTML
if (!gasLimit) {
try {
gasLimit = await call.estimateGas({ from, gasPrice })
} catch (e) {
return callbackFunc('Your transaction cannot be mined at the moment. Please, try again in a few blocks.')
}
openErrorModal('Error', errorMessage)
}
call.send({
from,
gasPrice,
gas: Math.ceil(gasLimit * 1.2) // +20% reserve to ensure enough gas
}, async function (error, txHash) {
if (error) {
let errorMessage = 'Your transaction wasn\'t processed, please try again in a few blocks.'
if (error.message) {
const detailsMessage = error.message.replace(/["]/g, '&quot;')
console.log(detailsMessage)
const detailsHTML = ` <a href="javascript:void(0);" data-boundary="window" data-container="body" data-html="false" data-placement="top" data-toggle="tooltip" title="${detailsMessage}" data-original-title="${detailsMessage}" class="link-helptip">Details</a>`
errorMessage = errorMessage + detailsHTML
}
callbackFunc(errorMessage)
} else {
try {
let tx
let currentBlockNumber
const maxWaitBlocks = 6
const startBlockNumber = (await web3.eth.getBlockNumber()) - 0
const finishBlockNumber = startBlockNumber + maxWaitBlocks
do {
await sleep(5) // seconds
tx = await web3.eth.getTransactionReceipt(txHash)
currentBlockNumber = await web3.eth.getBlockNumber()
} while (tx === null && currentBlockNumber <= finishBlockNumber)
if (tx) {
if (tx.status === true || tx.status === '0x1') {
callbackFunc() // success
} else {
callbackFunc('Transaction reverted')
}
} else {
callbackFunc(`Your transaction wasn't processed in ${maxWaitBlocks} blocks. Please, try again with the increased gas price or fixed nonce (use Reset Account feature of MetaMask).`)
}
} catch (e) {
callbackFunc(e.message)
}
}
})
}
export function setupChart ($canvas, self, total) {
@ -107,3 +131,7 @@ export function isSupportedNetwork (store) {
openWarningModal('Unauthorized', 'Please, connect to the xDai Chain.<br /><a href="https://xdaichain.com" target="_blank">Instructions</a>')
return false
}
function sleep (seconds) {
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
}

Loading…
Cancel
Save