diff --git a/js/src/modals/CreateAccount/createAccount.js b/js/src/modals/CreateAccount/createAccount.js index 9781e2a4c..908d1a9aa 100644 --- a/js/src/modals/CreateAccount/createAccount.js +++ b/js/src/modals/CreateAccount/createAccount.js @@ -310,17 +310,13 @@ class CreateAccount extends Component { } onCreate = () => { - this.store.setBusy(true); - return this.store .createAccount(this.vaultStore) .then(() => { - this.store.setBusy(false); this.store.nextStage(); this.props.onUpdate && this.props.onUpdate(); }) .catch((error) => { - this.store.setBusy(false); this.props.newError(error); }); } diff --git a/js/src/modals/CreateAccount/createAccount.test.js b/js/src/modals/CreateAccount/createAccount.test.js index 1cbc62329..31ddd56b0 100644 --- a/js/src/modals/CreateAccount/createAccount.test.js +++ b/js/src/modals/CreateAccount/createAccount.test.js @@ -17,6 +17,7 @@ import BigNumber from 'bignumber.js'; import sinon from 'sinon'; +import Api from '~/api'; import Store from './store'; const ADDRESS = '0x00000123456789abcdef123456789abcdef123456789abcdef'; @@ -45,7 +46,8 @@ function createApi () { setAccountName: sinon.stub().resolves(), listVaults: sinon.stub().resolves([]), listOpenedVaults: sinon.stub().resolves([]) - } + }, + util: Api.util }; } diff --git a/js/src/modals/CreateAccount/store.js b/js/src/modals/CreateAccount/store.js index 3ded358b4..dc39e166c 100644 --- a/js/src/modals/CreateAccount/store.js +++ b/js/src/modals/CreateAccount/store.js @@ -69,7 +69,7 @@ export default class Store { return !(this.nameError || this.walletFileError); case 'fromNew': - return !(this.nameError || this.passwordRepeatError); + return !(this.nameError || this.passwordRepeatError) && this.hasAddress && this.hasPhrase; case 'fromPhrase': return !(this.nameError || this.passwordRepeatError || this.passPhraseError); @@ -90,6 +90,10 @@ export default class Store { return !!(this.address); } + @computed get hasPhrase () { + return this.phrase.length !== 0; + } + @computed get passwordRepeatError () { return this.password === this.passwordRepeat ? null @@ -102,7 +106,7 @@ export default class Store { this.passwordRepeat = ''; this.phrase = ''; this.name = ''; - this.nameError = null; + this.nameError = ERRORS.noName; this.rawKey = ''; this.rawKeyError = null; this.vaultName = ''; @@ -228,6 +232,10 @@ export default class Store { } @action nextStage = () => { + if (this.stage === 0) { + this.clearErrors(); + } + this.stage++; } @@ -236,6 +244,10 @@ export default class Store { } createAccount = (vaultStore) => { + if (!this.canCreate) { + return false; + } + this.setBusy(true); return this diff --git a/js/src/modals/CreateAccount/store.spec.js b/js/src/modals/CreateAccount/store.spec.js index 3de24fbbc..11a8bf117 100644 --- a/js/src/modals/CreateAccount/store.spec.js +++ b/js/src/modals/CreateAccount/store.spec.js @@ -89,7 +89,7 @@ describe('modals/CreateAccount/Store', () => { store.clearErrors(); expect(store.name).to.equal(''); - expect(store.nameError).to.be.null; + expect(store.nameError).not.to.be.null; expect(store.password).to.equal(''); expect(store.passwordRepeatError).to.be.null; expect(store.rawKey).to.equal(''); @@ -293,6 +293,7 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromJSON/fromPresale', () => { beforeEach(() => { store.setCreateType('fromJSON'); + store.setName('blah'); }); it('returns true on no errors', () => { @@ -313,6 +314,9 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromNew', () => { beforeEach(() => { store.setCreateType('fromNew'); + store.setAddress('0x0000000000000000000000000000000000000000'); + store.setName('blah'); + store.setPhrase('testing'); }); it('returns true on no errors', () => { @@ -324,6 +328,12 @@ describe('modals/CreateAccount/Store', () => { expect(store.canCreate).to.be.false; }); + it('returns false on no phrase', () => { + store.setPhrase(''); + + expect(store.canCreate).to.be.false; + }); + it('returns false on passwordRepeatError', () => { store.setPassword('testing'); expect(store.canCreate).to.be.false; @@ -333,6 +343,7 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromPhrase', () => { beforeEach(() => { store.setCreateType('fromPhrase'); + store.setName('name'); }); it('returns true on no errors', () => { @@ -353,6 +364,8 @@ describe('modals/CreateAccount/Store', () => { describe('createType === fromRaw', () => { beforeEach(() => { store.setCreateType('fromRaw'); + store.setName('name'); + store.setRawKey('0x1000000000000000000000000000000000000000000000000000000000000000'); }); it('returns true on no errors', () => { @@ -370,7 +383,7 @@ describe('modals/CreateAccount/Store', () => { }); it('returns false on rawKeyError', () => { - store.setRawKey('testing'); + store.setRawKey('0x1'); expect(store.canCreate).to.be.false; }); }); @@ -415,6 +428,9 @@ describe('modals/CreateAccount/Store', () => { createAccountFromPhraseSpy = sinon.spy(store, 'createAccountFromPhrase'); createAccountFromRawSpy = sinon.spy(store, 'createAccountFromRaw'); busySpy = sinon.spy(store, 'setBusy'); + + store.setName('name'); + store.setPhrase('testing'); }); afterEach(() => { @@ -432,6 +448,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromGeth on createType === fromGeth', () => { store.setCreateType('fromGeth'); + store.setGethAccountsAvailable(GETH_ADDRESSES); + store.selectGethAccount(GETH_ADDRESSES[0]); return store.createAccount().then(() => { expect(createAccountFromGethSpy).to.have.been.called; @@ -440,6 +458,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromWallet on createType === fromJSON', () => { store.setCreateType('fromJSON'); + store.setName('name'); + store.setWalletJson('{}'); return store.createAccount().then(() => { expect(createAccountFromWalletSpy).to.have.been.called; @@ -448,6 +468,9 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromPhrase on createType === fromNew', () => { store.setCreateType('fromNew'); + store.setName('name'); + store.setPhrase('phrase'); + store.setAddress('0x1234567890123456789012345678901234567890'); return store.createAccount().then(() => { expect(createAccountFromPhraseSpy).to.have.been.called; @@ -456,6 +479,9 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromPhrase on createType === fromPhrase', () => { store.setCreateType('fromPhrase'); + store.setName('name'); + store.setPhrase('phrase'); + store.setAddress('0x1234567890123456789012345678901234567890'); return store.createAccount().then(() => { expect(createAccountFromPhraseSpy).to.have.been.called; @@ -464,6 +490,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromWallet on createType === fromPresale', () => { store.setCreateType('fromPresale'); + store.setName('name'); + store.setWalletJson('{}'); return store.createAccount().then(() => { expect(createAccountFromWalletSpy).to.have.been.called; @@ -472,6 +500,8 @@ describe('modals/CreateAccount/Store', () => { it('calls createAccountFromRaw on createType === fromRaw', () => { store.setCreateType('fromRaw'); + store.setName('name'); + store.setRawKey('0x1000000000000000000000000000000000000000000000000000000000000000'); return store.createAccount().then(() => { expect(createAccountFromRawSpy).to.have.been.called; @@ -481,6 +511,9 @@ describe('modals/CreateAccount/Store', () => { it('moves account to vault when vaultName set', () => { store.setCreateType('fromNew'); store.setVaultName('testing'); + store.setName('name'); + store.setAddress('0x1234567890123456789012345678901234567890'); + store.setPhrase('phrase'); return store.createAccount(vaultStore).then(() => { expect(vaultStore.moveAccount).to.have.been.calledWith('testing', ADDRESS); @@ -489,6 +522,9 @@ describe('modals/CreateAccount/Store', () => { it('sets and rests the busy flag', () => { store.setCreateType('fromNew'); + store.setName('name'); + store.setAddress('0x1234567890123456789012345678901234567890'); + store.setPhrase('phrase'); return store.createAccount().then(() => { expect(busySpy).to.have.been.calledWith(true); diff --git a/js/src/redux/providers/status.js b/js/src/redux/providers/status.js index f671fbabe..4a28f0f38 100644 --- a/js/src/redux/providers/status.js +++ b/js/src/redux/providers/status.js @@ -291,9 +291,10 @@ export default class Status { netPeers, clientVersion, netVersion, defaultExtraData, netChain, netPort, rpcSettings, enode, upgradeStatus ]) => { const isTest = [ - '2', // morden - '3', // ropsten - '42' // kovan + '2', // morden + '3', // ropsten, + '17', // devchain + '42' // kovan ].includes(netVersion); const longStatus = { diff --git a/js/src/ui/TxList/TxRow/txRow.js b/js/src/ui/TxList/TxRow/txRow.js index bad9ca9d2..512f52c66 100644 --- a/js/src/ui/TxList/TxRow/txRow.js +++ b/js/src/ui/TxList/TxRow/txRow.js @@ -204,31 +204,36 @@ class TxRow extends Component { if (!isCancelOpen && !isEditOpen) { const pendingStatus = this.getCondition(); + const isPending = pendingStatus === 'pending'; - if (pendingStatus === 'submitting') { - return ( -
-
-
- -
-
- ); - } return (
- - { pendingStatus } - -
- -
+ { + isPending + ? ( +
+
+
+ +
+
+ ) : ( +
+ + { pendingStatus } + +
+ +
+
+ ) + } + { isPending + ? ( +
+ +
+ ) : null + }
); } @@ -308,11 +323,10 @@ class TxRow extends Component { getCondition = () => { const { blockNumber, tx } = this.props; - let { time, block } = tx.condition; + let { time, block = 0 } = tx.condition || {}; if (time) { if ((time.getTime() - Date.now()) >= 0) { - // return `${dateDifference(new Date(), time, { compact: true })} left`; return ( ); - } else { - return 'submitting'; } - } else if (blockNumber) { + } + + if (blockNumber) { block = blockNumber.minus(block); - // return (block.toNumber() < 0) - // ? block.abs().toFormat(0) + ' blocks left' - // : 'submitting'; if (block.toNumber() < 0) { return ( ); - } else { - return 'submitting'; } } + + return 'pending'; } cancelTx = () => { diff --git a/js/src/views/Signer/components/RequestOrigin/requestOrigin.js b/js/src/views/Signer/components/RequestOrigin/requestOrigin.js index 6582e9780..7b0f9cd19 100644 --- a/js/src/views/Signer/components/RequestOrigin/requestOrigin.js +++ b/js/src/views/Signer/components/RequestOrigin/requestOrigin.js @@ -29,7 +29,12 @@ export default class RequestOrigin extends Component { static propTypes = { origin: PropTypes.shape({ type: PropTypes.oneOf(['unknown', 'dapp', 'rpc', 'ipc', 'signer']), - details: PropTypes.string.isRequired + details: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.shape({ + session: PropTypes.string.isRequired + }) + ]).isRequired }).isRequired }; @@ -126,7 +131,9 @@ export default class RequestOrigin extends Component { } if (origin.type === 'signer') { - return this.renderSigner(origin.details); + const session = origin.details && origin.details.session || origin.details; + + return this.renderSigner(session); } }