diff --git a/package-lock.json b/package-lock.json index df47f29df..55bcf838a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5488,6 +5488,11 @@ "resolved": "https://registry.npmjs.org/final-form-calculate/-/final-form-calculate-1.1.0.tgz", "integrity": "sha512-a5GIFDn7KEejkamxS/npZysmfvNKt9WfqqmDJRewwRkooOD4icVvB1Plpnkx4MGhgWAN6pg0yTjH002fQppGlg==" }, + "final-form-set-field-touched": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/final-form-set-field-touched/-/final-form-set-field-touched-1.0.0.tgz", + "integrity": "sha512-HybhN2L7EbEHxIOHxHuniAUZJmUqPJhJ8/a0fZADFNm969N6JZnk9LYKW+SU7Ni5Gddpj2xx1sWAMBfr7FGBCg==" + }, "finalhandler": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", diff --git a/package.json b/package.json index dd91e847a..d0a300d38 100755 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "final-form": "^4.3.1", "final-form-arrays": "^1.0.4", "final-form-calculate": "^1.1.0", + "final-form-set-field-touched": "^1.0.0", "font-awesome": "^4.7.0", "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", diff --git a/src/App.js b/src/App.js index f98b5612a..7e6c669cb 100644 --- a/src/App.js +++ b/src/App.js @@ -16,11 +16,10 @@ import { } from './components/index' import NoWeb3 from './components/Common/NoWeb3' import IncompleteDeploy from './components/IncompleteDeploy' -import { getQueryVariable } from './utils/utils' +import { getAddr, toast } from './utils/utils' import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' import AlertContainer from 'react-alert' import { TOAST } from './utils/constants' -import { toast } from './utils/utils' import { Web3Provider } from './react-web3' @inject('deploymentStore') @@ -28,7 +27,7 @@ import { Web3Provider } from './react-web3' class App extends Component { render() { const { deploymentStore } = this.props - var crowdsaleAddr = getQueryVariable('addr') + let crowdsaleAddr = getAddr() return ( diff --git a/src/components/Common/ButtonContinue.js b/src/components/Common/ButtonContinue.js new file mode 100644 index 000000000..c8d9a5ed3 --- /dev/null +++ b/src/components/Common/ButtonContinue.js @@ -0,0 +1,21 @@ +import React, { Component } from 'react' +import classNames from 'classnames' + +export class ButtonContinue extends Component { + /** + * Render method for ButtonContinue component + * @returns {*} + */ + render() { + const { status, type } = this.props + const submitButtonClass = classNames('button', 'button_fill', 'button_no_border', { + button_disabled: !status + }) + + return ( + + ) + } +} diff --git a/src/components/Home/index.js b/src/components/Home/index.js index 8ddcba045..69635501a 100644 --- a/src/components/Home/index.js +++ b/src/components/Home/index.js @@ -1,6 +1,5 @@ import React, { Component } from 'react' import '../../assets/stylesheets/application.css' -import { Link } from 'react-router-dom' import CrowdsalesList from '../Common/CrowdsalesList' import { Loader } from '../Common/Loader' import { loadRegistryAddresses } from '../../utils/blockchainHelpers' @@ -11,74 +10,132 @@ import { inject, observer } from 'mobx-react' import { checkWeb3, getNetworkVersion } from '../../utils/blockchainHelpers' import { getCrowdsaleAssets } from '../../stores/utils' import logdown from 'logdown' +import storage from 'store2' const logger = logdown('TW:home') const { CROWDSALE_STRATEGY, TOKEN_SETUP, CROWDSALE_SETUP, PUBLISH, CROWDSALE_PAGE } = NAVIGATION_STEPS -@inject('web3Store', 'generalStore', 'contractStore') +@inject( + 'web3Store', + 'generalStore', + 'contractStore', + 'crowdsaleStore', + 'gasPriceStore', + 'deploymentStore', + 'reservedTokenStore', + 'stepTwoValidationStore', + 'tierStore', + 'tokenStore' +) @observer export class Home extends Component { + state = { + showModal: false, + loading: false + } + constructor(props) { super(props) - this.state = { - showModal: false, - loading: false - } let { contractStore } = this.props contractStore.setProperty('downloadStatus', DOWNLOAD_STATUS.PENDING) } - componentDidMount() { - let { generalStore, web3Store, contractStore } = this.props - checkWeb3(web3Store.web3) - - getNetworkVersion() - .then(networkID => { - generalStore.setProperty('networkID', networkID) - getCrowdsaleAssets(networkID) - }) - .then( - () => { - contractStore.setProperty('downloadStatus', DOWNLOAD_STATUS.SUCCESS) - }, - e => { - logger.error('Error downloading contracts', e) - toast.showToaster({ - type: TOAST.TYPE.ERROR, - message: - 'The contracts could not be downloaded.Please try to refresh the page. If the problem persists, try again later.' - }) - - contractStore.setProperty('downloadStatus', DOWNLOAD_STATUS.FAILURE) - } - ) + async componentDidMount() { + let { web3Store } = this.props + await checkWeb3(web3Store.web3) } - chooseContract = () => { + chooseContract = async () => { this.setState({ loading: true }) - loadRegistryAddresses().then( - () => { - this.setState({ - loading: false, - showModal: true - }) - }, - e => { - logger.error('There was a problem loading the crowdsale addresses from the registry', e) - this.setState({ - loading: false - }) + try { + await loadRegistryAddresses() + this.setState({ + loading: false, + showModal: true + }) + } catch (e) { + logger.error('There was a problem loading the crowdsale addresses from the registry', e) + this.setState({ + loading: false + }) + } + } + + goNextStep = async () => { + // Clear local storage if there is no incomplete deployment, and reload + if (storage.has('DeploymentStore') && storage.get('DeploymentStore').deploymentStep) { + this.props.history.push('/') + } else { + this.clearStorage() + await this.reloadStorage() + this.props.history.push('1') + } + } + + async reloadStorage() { + let { generalStore, contractStore } = this.props + + try { + // General store, check network + let networkID = await getNetworkVersion() + generalStore.setProperty('networkID', networkID) + + // Contract store, get contract and abi + await getCrowdsaleAssets(networkID) + contractStore.setProperty('downloadStatus', DOWNLOAD_STATUS.SUCCESS) + } catch (e) { + logger.error('Error downloading contracts', e) + toast.showToaster({ + type: TOAST.TYPE.ERROR, + message: + 'The contracts could not be downloaded.Please try to refresh the page. If the problem persists, try again later.' + }) + contractStore.setProperty('downloadStatus', DOWNLOAD_STATUS.FAILURE) + } + } + + clearStorage() { + // Generate of stores to clear + const toArray = ({ + generalStore, + contractStore, + crowdsaleStore, + gasPriceStore, + deploymentStore, + reservedTokenStore, + stepTwoValidationStore, + tierStore, + tokenStore + }) => { + return [ + generalStore, + contractStore, + crowdsaleStore, + gasPriceStore, + deploymentStore, + reservedTokenStore, + stepTwoValidationStore, + tierStore, + tokenStore + ] + } + + const storesToClear = toArray(this.props) + for (let storeToClear of storesToClear) { + if (typeof storeToClear.reset === 'function') { + logger.log('Store to be cleared:', storeToClear.constructor.name) + storeToClear.reset() } - ) + } } onClick = crowdsaleAddress => { - this.props.history.push('/manage/' + crowdsaleAddress) + this.props.history.push(`manage/${crowdsaleAddress}`) } hideModal = () => { @@ -99,9 +156,9 @@ export class Home extends Component {
Token Wizard is powered by Auth-os.

- - New crowdsale - +
this.chooseContract()} className="button button_outline"> Choose Crowdsale
diff --git a/src/components/stepOne/index.js b/src/components/stepOne/index.js index 3c5a6ec89..9d9c07474 100644 --- a/src/components/stepOne/index.js +++ b/src/components/stepOne/index.js @@ -1,44 +1,72 @@ -import React from 'react' +import React, { Component } from 'react' import '../../assets/stylesheets/application.css' import { Link } from 'react-router-dom' import { StepNavigation } from '../Common/StepNavigation' +import { inject, observer } from 'mobx-react' +import { ButtonContinue } from '../Common/ButtonContinue' +import { checkWeb3 } from '../../utils/blockchainHelpers' import { NAVIGATION_STEPS, CROWDSALE_STRATEGIES, CROWDSALE_STRATEGIES_DISPLAYNAMES, DOWNLOAD_STATUS } from '../../utils/constants' -import { inject, observer } from 'mobx-react' -import classNames from 'classnames' import logdown from 'logdown' +import { Loader } from '../Common/Loader' -const logger = logdown('TW:components:stepOne') +const logger = logdown('TW:stepOne') const { CROWDSALE_STRATEGY } = NAVIGATION_STEPS +const { MINTED_CAPPED_CROWDSALE, DUTCH_AUCTION } = CROWDSALE_STRATEGIES -@inject('crowdsaleStore', 'contractStore') +@inject('crowdsaleStore', 'contractStore', 'web3Store') @observer -export class stepOne extends React.Component { - constructor(props) { - super(props) - - this.setStrategy(null, CROWDSALE_STRATEGIES.MINTED_CAPPED_CROWDSALE) +export class stepOne extends Component { + state = { + loading: false, + strategy: null } - setStrategy = (event, strategy) => { - if (!strategy) { - strategy = event.target.id + async componentDidMount() { + const { crowdsaleStore, web3Store } = this.props + await checkWeb3(web3Store.web3) + + this.setState({ loading: true }) + logger.log('CrowdsaleStore strategy', crowdsaleStore.strategy) + + // Set default value + if (crowdsaleStore && !crowdsaleStore.strategy) { + crowdsaleStore.setProperty('strategy', MINTED_CAPPED_CROWDSALE) } - this.props.crowdsaleStore.setProperty('strategy', strategy) + + this.setState({ + loading: false, + strategy: crowdsaleStore.strategy + }) + } + + /** + * Handle radio input and set value for strategy + * @param e + */ + handleChange = e => { + const { crowdsaleStore } = this.props + const strategy = e.currentTarget.value + + crowdsaleStore.setProperty('strategy', strategy) + this.setState({ + strategy: crowdsaleStore.strategy + }) + logger.log('CrowdsaleStore strategy selected:', strategy) } + /** + * Render method for stepOne component + * @returns {*} + */ render() { const { contractStore } = this.props - let status = contractStore.downloadStatus === DOWNLOAD_STATUS.SUCCESS && localStorage.length > 0 - logger.log('Contract store status', status) - const submitButtonClass = classNames('button', 'button_fill', 'button_no_border', { - button_disabled: !status - }) + let status = (contractStore && contractStore.downloadStatus === DOWNLOAD_STATUS.SUCCESS) || localStorage.length > 0 return (
@@ -49,13 +77,15 @@ export class stepOne extends React.Component {

{CROWDSALE_STRATEGY}

Select a strategy for your crowdsale.

-
+
@@ -71,11 +108,10 @@ export class stepOne extends React.Component {
- +
+ ) } diff --git a/src/components/stepTwo/StepTwoForm.js b/src/components/stepTwo/StepTwoForm.js index 9bd0801b9..7884a89f4 100644 --- a/src/components/stepTwo/StepTwoForm.js +++ b/src/components/stepTwo/StepTwoForm.js @@ -6,7 +6,7 @@ import { TokenDecimals } from '../Common/TokenDecimals' import { TokenSupply } from '../Common/TokenSupply' import { ReservedTokensInputBlock } from '../Common/ReservedTokensInputBlock' import { CROWDSALE_STRATEGIES } from '../../utils/constants' -import classNames from 'classnames' +import { ButtonContinue } from '../Common/ButtonContinue' const errorStyle = { color: 'red', @@ -30,12 +30,12 @@ export const StepTwoForm = ({ crowdsaleStore, invalid, pristine, - submitting + submitting, + mutators: { setFieldTouched }, + reload, + form }) => { - // Build disable class to use in the submit button - const submitButtonClass = classNames('button', 'button_fill', 'button_no_border', { - button_disabled: submitting || pristine || invalid - }) + const status = !(submitting || invalid) const reservedTokens = (
@@ -53,6 +53,20 @@ export const StepTwoForm = ({
) + const setFieldAsTouched = ({ values, errors }) => { + if (reload) { + form.mutators.setFieldTouched('name', true) + form.mutators.setFieldTouched('ticker', true) + form.mutators.setFieldTouched('decimals', true) + form.mutators.setFieldTouched('supply', true) + } + } + + const onChangeForm = ({ values, errors }) => { + updateTokenStore({ values, errors }) + setFieldAsTouched({ values, errors }) + } + return (
@@ -66,12 +80,10 @@ export const StepTwoForm = ({ {crowdsaleStore.strategy === CROWDSALE_STRATEGIES.MINTED_CAPPED_CROWDSALE ? reservedTokens : null}
- +
- + ) } diff --git a/src/components/stepTwo/index.js b/src/components/stepTwo/index.js index e2d5ef077..590f77f29 100644 --- a/src/components/stepTwo/index.js +++ b/src/components/stepTwo/index.js @@ -9,6 +9,8 @@ import { inject, observer } from 'mobx-react' import { Form } from 'react-final-form' import { StepTwoForm } from './StepTwoForm' import logdown from 'logdown' +import { sleep, toBigNumber } from '../../utils/utils' +import setFieldTouched from 'final-form-set-field-touched' const { TOKEN_SETUP } = NAVIGATION_STEPS const { VALID, INVALID } = VALIDATION_TYPES @@ -19,25 +21,36 @@ const logger = logdown('TW:stepTwo:index') @inject('tokenStore', 'crowdsaleStore', 'web3Store', 'reservedTokenStore') @observer export class stepTwo extends Component { - constructor(props) { - super(props) - - this.state = { - loading: true - } + state = { + loading: false, + tokenValues: {}, + reload: false } async componentDidMount() { - const { tokenStore, web3Store, crowdsaleStore } = this.props + const { web3Store } = this.props await checkWeb3(web3Store.web3) + this.setState({ loading: true }) + const tokenValues = await this.load() + logger.log('Token Values', tokenValues) + this.setState({ loading: false, tokenValues }) + } + + async load() { + const { tokenStore, crowdsaleStore, reservedTokenStore } = this.props + + await sleep(1000) if (tokenStore.isEmpty(crowdsaleStore)) { tokenStore.addTokenSetup() + } else { + this.setState({ + reload: true + }) } - - this.tokenValues = tokenStore.getToken(crowdsaleStore) - - this.setState({ loading: false }) + const token = tokenStore.getToken(crowdsaleStore) + reservedTokenStore.applyDecimalsToTokens(token.decimals) + return token } removeReservedToken = index => { @@ -53,6 +66,7 @@ export class stepTwo extends Component { if (result && result.value) { reservedTokenStore.clearAll() } + return result } validateReservedTokensList = () => { @@ -71,6 +85,11 @@ export class stepTwo extends Component { reservedTokenStore.addToken(newToken) } + /** + * Callback to update the token store + * @param values + * @param errors + */ updateTokenStore = ({ values, errors }) => { const { tokenStore } = this.props @@ -80,14 +99,20 @@ export class stepTwo extends Component { }) } + /** + * Goto to the step 3 on submit + */ onSubmit = () => { this.props.history.push('/3') } render() { const { reservedTokenStore, crowdsaleStore, tokenStore } = this.props + const { isMintedCappedCrowdsale } = crowdsaleStore const decimals = - tokenStore.validToken.decimals === VALID && tokenStore.decimals >= 0 ? parseInt(tokenStore.decimals, 10) : 0 + tokenStore.validToken.decimals === VALID && tokenStore.decimals >= 0 + ? toBigNumber(tokenStore.decimals).toFixed() + : 0 return (
@@ -99,10 +124,12 @@ export class stepTwo extends Component {

Configure properties of your token. Created token will be ERC-20 compatible.

{ this[property] = value } + + @action + reset = () => { + this.MintedCappedProxy = undefined + this.DutchProxy = undefined + this.ProxiesRegistry = undefined + this.abstractStorage = undefined + this.registryIdx = undefined + this.provider = undefined + this.registryExec = undefined + this.idxMintedCapped = undefined + this.saleMintedCapped = undefined + this.saleManagerMintedCapped = undefined + this.tokenMintedCapped = undefined + this.tokenManagerMintedCapped = undefined + this.idxDutch = undefined + this.saleDutch = undefined + this.tokenDutch = undefined + this.crowdsale = undefined + this.downloadStatus = undefined + } } export default ContractStore diff --git a/src/stores/CrowdsaleStore.js b/src/stores/CrowdsaleStore.js index b976e0481..4b7a55869 100644 --- a/src/stores/CrowdsaleStore.js +++ b/src/stores/CrowdsaleStore.js @@ -107,6 +107,11 @@ class CrowdsaleStore { updatable: false, initialTiersValues: [] } + this.strategy = undefined + this.maximumSellableTokens = undefined + this.maximumSellableTokensInWei = undefined + this.supply = undefined + this.endTime = undefined } @action diff --git a/src/stores/DeploymentStore.js b/src/stores/DeploymentStore.js index 9f8e71cf7..7bfafbedf 100644 --- a/src/stores/DeploymentStore.js +++ b/src/stores/DeploymentStore.js @@ -12,6 +12,7 @@ class DeploymentStore { @observable invalidAccount = false constructor() { + this.reset() autosave(this, 'DeploymentStore', store => { const txMap = new Map() Object.keys(store.txMap).forEach(key => { @@ -153,6 +154,15 @@ class DeploymentStore { get deployInProgress() { return this.deploymentStep !== null } + + @action + reset = () => { + this.txMap = new Map() + this.deploymentStep = null + this.hasEnded = false + this.deployerAccount = null + this.invalidAccount = false + } } export default DeploymentStore diff --git a/src/stores/GasPriceStore.js b/src/stores/GasPriceStore.js index ff20ed99c..08d0a43cc 100644 --- a/src/stores/GasPriceStore.js +++ b/src/stores/GasPriceStore.js @@ -15,31 +15,7 @@ class GasPriceStore { @observable health constructor() { - this.slow = { - id: GAS_PRICE.SLOW.ID, - price: GAS_PRICE.SLOW.PRICE - } - - this.standard = { - id: GAS_PRICE.NORMAL.ID, - price: GAS_PRICE.NORMAL.PRICE - } - - this.fast = { - id: GAS_PRICE.FAST.ID, - price: GAS_PRICE.FAST.PRICE - } - - this.instant = { - id: GAS_PRICE.INSTANT.ID, - price: GAS_PRICE.INSTANT.PRICE - } - - this.custom = { - id: GAS_PRICE.CUSTOM.ID, - price: GAS_PRICE.CUSTOM.PRICE - } - + this.reset() autosave(this, 'GasPriceStore') } @@ -114,6 +90,38 @@ class GasPriceStore { price: weiToGwei(gasPrice.price) })) } + + @action + reset = () => { + this.slow = { + id: GAS_PRICE.SLOW.ID, + price: GAS_PRICE.SLOW.PRICE + } + + this.standard = { + id: GAS_PRICE.NORMAL.ID, + price: GAS_PRICE.NORMAL.PRICE + } + + this.fast = { + id: GAS_PRICE.FAST.ID, + price: GAS_PRICE.FAST.PRICE + } + + this.instant = { + id: GAS_PRICE.INSTANT.ID, + price: GAS_PRICE.INSTANT.PRICE + } + + this.custom = { + id: GAS_PRICE.CUSTOM.ID, + price: GAS_PRICE.CUSTOM.PRICE + } + + this.block_number = undefined + this.block_time = undefined + this.health = undefined + } } export default GasPriceStore diff --git a/src/stores/GeneralStore.js b/src/stores/GeneralStore.js index daaeef416..4c496e2c3 100644 --- a/src/stores/GeneralStore.js +++ b/src/stores/GeneralStore.js @@ -7,6 +7,7 @@ class GeneralStore { @observable gasPrice = GAS_PRICE.FAST.PRICE constructor() { + this.reset() autosave(this, 'GeneralStore') } @@ -19,6 +20,12 @@ class GeneralStore { setGasPrice = gasPrice => { this.gasPrice = gasPrice } + + @action + reset = () => { + this.networkID = undefined + this.gasPrice = GAS_PRICE.FAST.PRICE + } } export default GeneralStore diff --git a/src/stores/ReservedTokenStore.js b/src/stores/ReservedTokenStore.js index 58074311b..d5009d405 100644 --- a/src/stores/ReservedTokenStore.js +++ b/src/stores/ReservedTokenStore.js @@ -1,7 +1,8 @@ import { observable, action } from 'mobx' import autosave from './autosave' -import { computed } from 'mobx/lib/mobx' +import { computed } from 'mobx' import { LIMIT_RESERVED_ADDRESSES } from '../utils/constants' +import { toBigNumber } from '../utils/utils' class ReservedTokenStore { @observable tokens @@ -59,6 +60,26 @@ class ReservedTokenStore { get validateLength() { return this.tokens.length < LIMIT_RESERVED_ADDRESSES } + + @action + reset = () => { + this.tokens = [] + } + + @action + applyDecimalsToTokens = (decimals = 0) => { + const decimalsInt = +decimals + if (decimalsInt > 18 || decimalsInt < 0) { + return + } + + for (let i = 0; i < this.tokens.length; i++) { + if (this.tokens && this.tokens[i] && this.tokens[i].val) { + const decimalsBN = toBigNumber(this.tokens[i].val) + this.tokens[i].val = decimalsBN.toFixed(+decimalsInt) + } + } + } } export default ReservedTokenStore diff --git a/src/stores/TokenStore.js b/src/stores/TokenStore.js index 8ed81d0d5..48a6a24af 100644 --- a/src/stores/TokenStore.js +++ b/src/stores/TokenStore.js @@ -73,12 +73,14 @@ class TokenStore { @action checkIsEmptyMinted = () => { - return !this.name || !this.ticker || !this.decimals + // The decimal field is not checked, because it has a default value + return !this.name && !this.ticker } @action checkIsEmptyDutch = () => { - return !this.name || !this.ticker || !this.decimals || !this.supply + // The decimal field is not checked, because it has a default value + return !this.name && !this.ticker && !this.supply } @action diff --git a/src/stores/index.js b/src/stores/index.js index f12fa77b3..8950af2b5 100644 --- a/src/stores/index.js +++ b/src/stores/index.js @@ -1,4 +1,3 @@ -import storage from 'store2' import ContractStore from './ContractStore' import ReservedTokenStore from './ReservedTokenStore' import StepTwoValidationStore from './StepTwoValidationStore' @@ -14,10 +13,8 @@ import DeploymentStore from './DeploymentStore' import StatsStore from './StatsStore' import localStorageMock from './localStorageMock.js' //for Jest unit tests -if (!window.localStorage) Object.defineProperty(window, 'localStorage', { value: localStorageMock }) -// Clear local storage if there is no incomplete deployment -if (storage.has('DeploymentStore') && storage.get('DeploymentStore').deploymentStep === null) { - localStorage.clear() +if (!window.localStorage) { + Object.defineProperty(window, 'localStorage', { value: localStorageMock }) } localStorage.debug = 'TW*' diff --git a/src/utils/blockchainHelpers.js b/src/utils/blockchainHelpers.js index 51ff856ed..122c852ea 100644 --- a/src/utils/blockchainHelpers.js +++ b/src/utils/blockchainHelpers.js @@ -477,7 +477,7 @@ export const getCrowdsaleStrategyByName = async appName => { export async function loadRegistryAddresses() { const crowdsales = await getOwnerApplicationsInstancesForProxy() - logger.log(crowdsales) + logger.log('Crowdsales', crowdsales) crowdsaleStore.setCrowdsales(crowdsales) } diff --git a/src/utils/utils.js b/src/utils/utils.js index 7ccbcd244..c7f2b357d 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -3,6 +3,7 @@ import queryString from 'query-string' import { CrowdsaleConfig } from '../components/Common/config' import { BigNumber } from 'bignumber.js' import logdown from 'logdown' +import Web3 from 'web3' const logger = logdown('TW:utils:utils') @@ -17,12 +18,18 @@ export const getExecID = () => { return isExecIDValid(execID) ? execID : null } -//todo: check address input +/** + * Get address from query param + * @returns {null} + */ export const getAddr = () => { const addr = getQueryVariable('addr') - logger.log('getAddr:', addr) - return addr + const addressIsValid = Web3.utils.isAddress(addr) + logger.log('Obtain address from query:', addr) + logger.log('Check if address is valid:', addressIsValid) + return addressIsValid ? addr : null } + export const isNetworkIDValid = networkID => /^[0-9]+$/.test(networkID) export const getNetworkID = () => { diff --git a/test/components/stepTwo/__snapshots__/StepTwoForm.spec.js.snap b/test/components/stepTwo/__snapshots__/StepTwoForm.spec.js.snap index 22e3639a1..a824a2a52 100644 --- a/test/components/stepTwo/__snapshots__/StepTwoForm.spec.js.snap +++ b/test/components/stepTwo/__snapshots__/StepTwoForm.spec.js.snap @@ -500,8 +500,8 @@ exports[`StepTwoForm should render StepTwoForm for Minted Capped Crowdsale 1`] = className="button-container" >