diff --git a/ui/src/components/Loading.js b/ui/src/components/Loading.js index 2a3eb7f0..6a83d4a2 100644 --- a/ui/src/components/Loading.js +++ b/ui/src/components/Loading.js @@ -9,9 +9,9 @@ export class Loading extends React.Component { render() { const { REACT_APP_UI_STYLES } = process.env const { alertStore } = this.props.RootStore - const { loadingStepIndex, loadingSteps, blockConfirmations } = alertStore + const { loadingStepIndex, loadingSteps, blockConfirmations, requiredBlockConfirmations } = alertStore const style = alertStore.showLoading ? { display: 'flex' } : { display: 'none' } - const progress = loadingStepIndex === 3 ? 100 : loadingStepIndex * 25 + blockConfirmations * 4 + const progress = loadingStepIndex === 3 ? 100 : 25 + (blockConfirmations / requiredBlockConfirmations) * 50 const radius = REACT_APP_UI_STYLES === 'stake' ? 33 : 40 return ( @@ -25,6 +25,7 @@ export class Loading extends React.Component { {loadingStepIndex > 0 && ( 1} progress={progress} radius={radius} diff --git a/ui/src/components/ProgressRing.js b/ui/src/components/ProgressRing.js index cdd2b96b..5e354ee4 100644 --- a/ui/src/components/ProgressRing.js +++ b/ui/src/components/ProgressRing.js @@ -7,17 +7,40 @@ export class ProgressRing extends Component { } render() { - const { radius, stroke, progress, confirmationNumber, hideConfirmationNumber } = this.props + const { + radius, + stroke, + progress, + confirmationNumber, + requiredBlockConfirmations, + hideConfirmationNumber + } = this.props const { REACT_APP_UI_STYLES } = process.env const { circumference, normalizedRadius } = this.state const strokeDashoffset = circumference - (progress / 100) * circumference - const confirmations = hideConfirmationNumber ? '' : `${confirmationNumber}/8` + const confirmations = hideConfirmationNumber ? '' : `${confirmationNumber}/${requiredBlockConfirmations}` const strokeColor = REACT_APP_UI_STYLES === 'stake' ? '#E6ECF1' : '#7b5ab2' const strokeProgressColor = REACT_APP_UI_STYLES === 'stake' ? '#4DA9A6' : '#60dc97' - const textParams = - REACT_APP_UI_STYLES === 'stake' - ? { x: '22', y: '38', font: 'Roboto', fontSize: '14', fill: '#242A31' } - : { x: '28', y: '47', font: 'Nunito', fontSize: '18', fill: 'white' } + + let textParams + if (REACT_APP_UI_STYLES === 'stake') { + const xPosTextParam = + requiredBlockConfirmations >= 10 && confirmationNumber >= 10 + ? '15' + : requiredBlockConfirmations >= 10 + ? '20' + : '22' + textParams = { x: xPosTextParam, y: '38', font: 'Roboto', fontSize: '14', fill: '#242A31' } + } else { + const xPosTextParam = + requiredBlockConfirmations >= 10 && confirmationNumber >= 10 + ? '16' + : requiredBlockConfirmations >= 10 + ? '22' + : '28' + textParams = { x: xPosTextParam, y: '47', font: 'Nunito', fontSize: '18', fill: 'white' } + } + const progressTransform = REACT_APP_UI_STYLES === 'stake' ? 'rotate(-90 33 33)' : '' return ( diff --git a/ui/src/stores/AlertStore.js b/ui/src/stores/AlertStore.js index 3e541f0e..3d4b7171 100644 --- a/ui/src/stores/AlertStore.js +++ b/ui/src/stores/AlertStore.js @@ -13,6 +13,9 @@ class AlertStore { @observable blockConfirmations = 0 + @observable + requiredBlockConfirmations = 8 + @observable showDailyQuotaInfo = false @@ -97,6 +100,11 @@ class AlertStore { this.blockConfirmations = blocks } + @action + setRequiredBlockConfirmations(blocks) { + this.requiredBlockConfirmations = blocks + } + @action setLoadingStepIndex(index) { this.loadingStepIndex = index diff --git a/ui/src/stores/ForeignStore.js b/ui/src/stores/ForeignStore.js index 66732789..4bf4f8d3 100644 --- a/ui/src/stores/ForeignStore.js +++ b/ui/src/stores/ForeignStore.js @@ -11,7 +11,8 @@ import { getTokenType, ERC20_BYTES32_ABI, getDeployedAtBlock, - isMediatorMode + isMediatorMode, + FOREIGN_AMB_ABI } from '../../../commons' import { getMaxPerTxLimit, @@ -32,7 +33,9 @@ import { getValidatorList, getValidatorContract, getRequiredSignatures, - getValidatorCount + getValidatorCount, + getRequiredBlockConfirmations, + getBridgeContract } from './utils/contract' import { balanceLoaded, removePendingTransaction } from './utils/testUtils' import sleep from './utils/sleep' @@ -112,6 +115,9 @@ class ForeignStore { @observable lastEventRelayedOnForeign = 0 + @observable + requiredBlockConfirmations = 8 + feeManager = { totalFeeDistributedFromSignatures: BN(0), totalFeeDistributedFromAffirmation: BN(0) @@ -124,6 +130,7 @@ class ForeignStore { COMMON_FOREIGN_BRIDGE_ADDRESS = process.env.REACT_APP_COMMON_FOREIGN_BRIDGE_ADDRESS explorerTxTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_TX_TEMPLATE || '' explorerAddressTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE || '' + ambBridgeContract = {} constructor(rootStore) { this.web3Store = rootStore.web3Store @@ -150,6 +157,7 @@ class ForeignStore { this.getTokenBalance() this.getCurrentLimit() this.getFee() + this.getRequiredBlockConfirmations() this.getValidators() this.getStatistics() this.getFeeEvents() @@ -504,6 +512,16 @@ class ForeignStore { } } } + + async getRequiredBlockConfirmations() { + if (isMediatorMode(this.rootStore.bridgeMode)) { + const foreignAMBBridgeContract = await getBridgeContract(this.foreignBridge) + this.ambBridgeContract = new this.foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, foreignAMBBridgeContract) + this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract) + } else { + this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.foreignBridge) + } + } } export default ForeignStore diff --git a/ui/src/stores/HomeStore.js b/ui/src/stores/HomeStore.js index 84928a66..1978faa3 100644 --- a/ui/src/stores/HomeStore.js +++ b/ui/src/stores/HomeStore.js @@ -14,7 +14,8 @@ import { ERC20_BYTES32_ABI, getDeployedAtBlock, isErcToErcMode, - isMediatorMode + isMediatorMode, + HOME_AMB_ABI } from '../../../commons' import { getMaxPerTxLimit, @@ -40,7 +41,9 @@ import { getValidatorContract, getRequiredSignatures, getValidatorCount, - getFee + getFee, + getRequiredBlockConfirmations, + getBridgeContract } from './utils/contract' import { balanceLoaded, removePendingTransaction } from './utils/testUtils' import sleep from './utils/sleep' @@ -147,6 +150,9 @@ class HomeStore { title: '' } + @observable + requiredBlockConfirmations = 8 + feeManager = { totalFeeDistributedFromSignatures: BN(0), totalFeeDistributedFromAffirmation: BN(0) @@ -160,6 +166,7 @@ class HomeStore { tokenContract = {} tokenDecimals = 18 blockRewardContract = {} + ambBridgeContract = {} constructor(rootStore) { this.homeWeb3 = rootStore.web3Store.homeWeb3 @@ -189,6 +196,7 @@ class HomeStore { this.getBalance() this.getCurrentLimit() this.getFee() + this.getRequiredBlockConfirmations() this.getValidators() this.getStatistics() this.getFeeEvents() @@ -638,6 +646,16 @@ class HomeStore { } } } + + async getRequiredBlockConfirmations() { + if (isMediatorMode(this.rootStore.bridgeMode)) { + const homeAMBBridgeContract = await getBridgeContract(this.homeBridge) + this.ambBridgeContract = new this.homeWeb3.eth.Contract(HOME_AMB_ABI, homeAMBBridgeContract) + this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract) + } else { + this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.homeBridge) + } + } } export default HomeStore diff --git a/ui/src/stores/TxStore.js b/ui/src/stores/TxStore.js index d8efadba..93163586 100644 --- a/ui/src/stores/TxStore.js +++ b/ui/src/stores/TxStore.js @@ -25,6 +25,10 @@ class TxStore { return } try { + const requiredConfirmations = + this.web3Store.metamaskNet.id === this.web3Store.homeNet.id + ? this.homeStore.requiredBlockConfirmations + : this.foreignStore.requiredBlockConfirmations const gasPrice = this.gasPriceStore.gasPriceInHex const gas = await estimateGas(this.web3Store.injectedWeb3, to, gasPrice, from, value, data) return this.web3Store.injectedWeb3.eth @@ -40,6 +44,7 @@ class TxStore { .on('transactionHash', hash => { console.log('txHash', hash) this.txsValues[hash] = sentValue + this.alertStore.setRequiredBlockConfirmations(requiredConfirmations) this.alertStore.setLoadingStepIndex(1) addPendingTransaction() this.getTxReceipt(hash) @@ -120,8 +125,8 @@ class TxStore { if (this.isStatusSuccess(res)) { if (this.web3Store.metamaskNet.id === this.web3Store.homeNet.id) { const blockConfirmations = this.homeStore.latestBlockNumber - res.blockNumber - if (blockConfirmations >= 8) { - this.alertStore.setBlockConfirmations(8) + if (blockConfirmations >= this.homeStore.requiredBlockConfirmations) { + this.alertStore.setBlockConfirmations(this.homeStore.requiredBlockConfirmations) this.alertStore.setLoadingStepIndex(2) if (yn(process.env.REACT_APP_UI_FOREIGN_WITHOUT_EVENTS)) { @@ -147,8 +152,8 @@ class TxStore { } } else { const blockConfirmations = this.foreignStore.latestBlockNumber - res.blockNumber - if (blockConfirmations >= 8) { - this.alertStore.setBlockConfirmations(8) + if (blockConfirmations >= this.foreignStore.requiredBlockConfirmations) { + this.alertStore.setBlockConfirmations(this.foreignStore.requiredBlockConfirmations) this.alertStore.setLoadingStepIndex(2) if (yn(process.env.REACT_APP_UI_HOME_WITHOUT_EVENTS)) { diff --git a/ui/src/stores/__tests__/HomeStore.test.js b/ui/src/stores/__tests__/HomeStore.test.js index 2cd9e94b..a5d4ad9b 100644 --- a/ui/src/stores/__tests__/HomeStore.test.js +++ b/ui/src/stores/__tests__/HomeStore.test.js @@ -34,6 +34,7 @@ describe('HomeStore', () => { contract.getRequiredSignatures = jest.fn(() => Promise.resolve(1)) contract.getValidatorCount = jest.fn(() => Promise.resolve(1)) contract.getValidatorList = jest.fn(() => Promise.resolve(['0x52576e0cCaA0C9157142Fbf1d1c6DbfAc5e4E33e'])) + contract.getRequiredBlockConfirmations = jest.fn(() => Promise.resolve(1)) // When new HomeStore(rootStore) diff --git a/ui/src/stores/utils/contract.js b/ui/src/stores/utils/contract.js index c47878ce..9df1a940 100644 --- a/ui/src/stores/utils/contract.js +++ b/ui/src/stores/utils/contract.js @@ -102,3 +102,10 @@ export const getValidatorContract = contract => contract.methods.validatorContra export const getRequiredSignatures = contract => contract.methods.requiredSignatures().call() export const getValidatorCount = contract => contract.methods.validatorCount().call() + +export const getRequiredBlockConfirmations = async contract => { + const blockConfirmations = await contract.methods.requiredBlockConfirmations().call() + return parseInt(blockConfirmations) +} + +export const getBridgeContract = contract => contract.methods.bridgeContract().call()