[beta] Backporting (#6676)
* Fix wallet view (#6597) * Add safe fail for empty logs * Filter transactions * Add more logging * Fix Wallet Creation and wallet tx list * Remove logs * Prevent selecting twice same wallet owner * Fix tests * Remove unused props * Remove unused props * Disallow pasting recovery phrases on first run (#6602) * Fix disallowing paste of recovery phrase on first run, ref #6581 * Allow the leader of CATS pasting recovery phrases. * Updated systemd files for linux (#6592) Previous version put $BASE directory in root directory. This version clearly explains how to run as root or as specific user. Additional configuration: * send SIGHUP for clean exit, * restart on fail. Tested on Ubuntu 16.04.3 LTS with 4.10.0-33-generic x86_64 kernel * Don't expose port 80 for parity anymore (#6633)
This commit is contained in:
parent
2d4f4bdd61
commit
949d2b7fd0
@ -35,6 +35,7 @@ export default class Store {
|
|||||||
@observable gethAddresses = [];
|
@observable gethAddresses = [];
|
||||||
@observable gethImported = [];
|
@observable gethImported = [];
|
||||||
@observable isBusy = false;
|
@observable isBusy = false;
|
||||||
|
@observable isTest = false;
|
||||||
@observable isWindowsPhrase = false;
|
@observable isWindowsPhrase = false;
|
||||||
@observable name = '';
|
@observable name = '';
|
||||||
@observable nameError = ERRORS.noName;
|
@observable nameError = ERRORS.noName;
|
||||||
@ -310,6 +311,10 @@ export default class Store {
|
|||||||
this.stage--;
|
this.stage--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action setIsTest = isTest => {
|
||||||
|
this.isTest = isTest;
|
||||||
|
}
|
||||||
|
|
||||||
createAccount = (vaultStore) => {
|
createAccount = (vaultStore) => {
|
||||||
if (!this.canCreate) {
|
if (!this.canCreate) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -16,18 +16,21 @@
|
|||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { Form, TypedInput, Input, AddressSelect, InputAddress } from '~/ui';
|
import { Form, TypedInput, Input, AddressSelect, InputAddress } from '~/ui';
|
||||||
|
|
||||||
import styles from '../createWallet.css';
|
import styles from '../createWallet.css';
|
||||||
|
|
||||||
export default class WalletDetails extends Component {
|
class WalletDetails extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accounts: PropTypes.object.isRequired,
|
accounts: PropTypes.object.isRequired,
|
||||||
wallet: PropTypes.object.isRequired,
|
wallet: PropTypes.object.isRequired,
|
||||||
errors: PropTypes.object.isRequired,
|
errors: PropTypes.object.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
walletType: PropTypes.string.isRequired
|
walletType: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
knownAddresses: PropTypes.array
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -103,7 +106,10 @@ export default class WalletDetails extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderMultisigDetails () {
|
renderMultisigDetails () {
|
||||||
const { accounts, wallet, errors } = this.props;
|
const { accounts, knownAddresses, wallet, errors } = this.props;
|
||||||
|
const allowedOwners = knownAddresses
|
||||||
|
// Exclude sender and already owners of the wallet
|
||||||
|
.filter((address) => !wallet.owners.includes(address) && address !== wallet.account);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form>
|
||||||
@ -163,7 +169,7 @@ export default class WalletDetails extends Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<TypedInput
|
<TypedInput
|
||||||
accounts={ accounts }
|
allowedValues={ allowedOwners }
|
||||||
label={
|
label={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='createWallet.details.ownersMulti.label'
|
id='createWallet.details.ownersMulti.label'
|
||||||
@ -249,3 +255,21 @@ export default class WalletDetails extends Component {
|
|||||||
this.props.onChange({ daylimit });
|
this.props.onChange({ daylimit });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapStateToProps (initState) {
|
||||||
|
const { accounts, contacts, contracts } = initState.personal;
|
||||||
|
const knownAddresses = [].concat(
|
||||||
|
Object.keys(accounts),
|
||||||
|
Object.keys(contacts),
|
||||||
|
Object.keys(contracts)
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => ({
|
||||||
|
knownAddresses
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(WalletDetails);
|
||||||
|
@ -25,6 +25,22 @@ import { ACCOUNTS } from '../createWallet.test.js';
|
|||||||
let component;
|
let component;
|
||||||
let onChange;
|
let onChange;
|
||||||
|
|
||||||
|
function createRedux () {
|
||||||
|
return {
|
||||||
|
dispatch: sinon.stub(),
|
||||||
|
subscribe: sinon.stub(),
|
||||||
|
getState: () => {
|
||||||
|
return {
|
||||||
|
personal: {
|
||||||
|
accounts: {},
|
||||||
|
contacts: {},
|
||||||
|
contracts: {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function render (walletType = 'MULTISIG') {
|
function render (walletType = 'MULTISIG') {
|
||||||
onChange = sinon.stub();
|
onChange = sinon.stub();
|
||||||
component = shallow(
|
component = shallow(
|
||||||
@ -36,7 +52,12 @@ function render (walletType = 'MULTISIG') {
|
|||||||
owners: []
|
owners: []
|
||||||
} }
|
} }
|
||||||
walletType={ walletType }
|
walletType={ walletType }
|
||||||
/>
|
/>,
|
||||||
|
{
|
||||||
|
context: {
|
||||||
|
store: createRedux()
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return component;
|
return component;
|
||||||
|
@ -283,7 +283,8 @@ export default class CreateWalletStore {
|
|||||||
|
|
||||||
const owners = _wallet.owners.filter((owner) => !/^(0x)?0*$/.test(owner));
|
const owners = _wallet.owners.filter((owner) => !/^(0x)?0*$/.test(owner));
|
||||||
|
|
||||||
if (_wallet.required > owners.length) {
|
// Real number of owners is owners + creator
|
||||||
|
if (_wallet.required > owners.length + 1) {
|
||||||
requiredValidation.valueError = 'the number of required validators should be lower or equal the number of owners';
|
requiredValidation.valueError = 'the number of required validators should be lower or equal the number of owners';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ export default class ParametersStep extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accounts: PropTypes.object.isRequired,
|
|
||||||
onParamsChange: PropTypes.func.isRequired,
|
onParamsChange: PropTypes.func.isRequired,
|
||||||
|
|
||||||
inputs: PropTypes.array,
|
inputs: PropTypes.array,
|
||||||
@ -60,7 +59,7 @@ export default class ParametersStep extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderConstructorInputs () {
|
renderConstructorInputs () {
|
||||||
const { accounts, params, paramsError } = this.props;
|
const { params, paramsError } = this.props;
|
||||||
const { inputs } = this.props;
|
const { inputs } = this.props;
|
||||||
|
|
||||||
if (!inputs || !inputs.length) {
|
if (!inputs || !inputs.length) {
|
||||||
@ -78,7 +77,6 @@ export default class ParametersStep extends Component {
|
|||||||
return (
|
return (
|
||||||
<div key={ index } className={ styles.funcparams }>
|
<div key={ index } className={ styles.funcparams }>
|
||||||
<TypedInput
|
<TypedInput
|
||||||
accounts={ accounts }
|
|
||||||
error={ error }
|
error={ error }
|
||||||
isEth={ false }
|
isEth={ false }
|
||||||
label={ label }
|
label={ label }
|
||||||
|
@ -313,7 +313,6 @@ class DeployContract extends Component {
|
|||||||
return (
|
return (
|
||||||
<ParametersStep
|
<ParametersStep
|
||||||
{ ...this.state }
|
{ ...this.state }
|
||||||
accounts={ accounts }
|
|
||||||
onParamsChange={ this.onParamsChange }
|
onParamsChange={ this.onParamsChange }
|
||||||
readOnly={ readOnly }
|
readOnly={ readOnly }
|
||||||
/>
|
/>
|
||||||
|
@ -177,7 +177,7 @@ export default class DetailsStep extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderParameters () {
|
renderParameters () {
|
||||||
const { accounts, func, values, valuesError, onValueChange } = this.props;
|
const { func, values, valuesError, onValueChange } = this.props;
|
||||||
|
|
||||||
if (!func) {
|
if (!func) {
|
||||||
return null;
|
return null;
|
||||||
@ -197,7 +197,6 @@ export default class DetailsStep extends Component {
|
|||||||
value={ values[index] }
|
value={ values[index] }
|
||||||
error={ valuesError[index] }
|
error={ valuesError[index] }
|
||||||
onChange={ onChange }
|
onChange={ onChange }
|
||||||
accounts={ accounts }
|
|
||||||
param={ input.type }
|
param={ input.type }
|
||||||
isEth={ false }
|
isEth={ false }
|
||||||
/>
|
/>
|
||||||
|
@ -78,16 +78,23 @@ class FirstRun extends Component {
|
|||||||
hasAccounts: PropTypes.bool.isRequired,
|
hasAccounts: PropTypes.bool.isRequired,
|
||||||
newError: PropTypes.func.isRequired,
|
newError: PropTypes.func.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
visible: PropTypes.bool.isRequired
|
visible: PropTypes.bool.isRequired,
|
||||||
|
isTest: PropTypes.bool.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
createStore = new CreateStore(this.context.api, {}, true, false);
|
createStore = new CreateStore(this.context.api, {}, this.props.isTest, false);
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
stage: 0,
|
stage: 0,
|
||||||
hasAcceptedTnc: false
|
hasAcceptedTnc: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (nextProps.isTest !== this.props.isTest) {
|
||||||
|
this.createStore.setIsTest(nextProps.isTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { visible } = this.props;
|
const { visible } = this.props;
|
||||||
const { stage } = this.state;
|
const { stage } = this.state;
|
||||||
@ -348,9 +355,10 @@ class FirstRun extends Component {
|
|||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const { hasAccounts } = state.personal;
|
const { hasAccounts } = state.personal;
|
||||||
|
const { isTest } = state.nodeStatus;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasAccounts
|
hasAccounts, isTest
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ function createRedux () {
|
|||||||
return {
|
return {
|
||||||
personal: {
|
personal: {
|
||||||
hasAccounts: false
|
hasAccounts: false
|
||||||
|
},
|
||||||
|
nodeStatus: {
|
||||||
|
isTest: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ class WalletSettings extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accountsInfo: PropTypes.object.isRequired,
|
|
||||||
wallet: PropTypes.object.isRequired,
|
wallet: PropTypes.object.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
senders: PropTypes.object.isRequired
|
senders: PropTypes.object.isRequired
|
||||||
@ -74,7 +73,7 @@ class WalletSettings extends Component {
|
|||||||
default:
|
default:
|
||||||
case 'EDIT':
|
case 'EDIT':
|
||||||
const { errors, fromString, wallet } = this.store;
|
const { errors, fromString, wallet } = this.store;
|
||||||
const { accountsInfo, senders } = this.props;
|
const { senders } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form>
|
<Form>
|
||||||
@ -143,7 +142,6 @@ class WalletSettings extends Component {
|
|||||||
}
|
}
|
||||||
value={ wallet.owners.slice() }
|
value={ wallet.owners.slice() }
|
||||||
onChange={ this.store.onOwnersChange }
|
onChange={ this.store.onOwnersChange }
|
||||||
accounts={ accountsInfo }
|
|
||||||
param='address[]'
|
param='address[]'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -443,13 +441,13 @@ class WalletSettings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps (initState, initProps) {
|
function mapStateToProps (initState, initProps) {
|
||||||
const { accountsInfo, accounts } = initState.personal;
|
const { accounts } = initState.personal;
|
||||||
const { owners } = initProps.wallet;
|
const { owners } = initProps.wallet;
|
||||||
|
|
||||||
const senders = pick(accounts, owners);
|
const senders = pick(accounts, owners);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
return { accountsInfo, senders };
|
return { senders };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { eq } from 'lodash';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
@ -93,6 +94,18 @@ class AddressSelect extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
|
if (!eq(Object.keys(this.props.accounts), Object.keys(nextProps.accounts))) {
|
||||||
|
return this.setValues(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eq(Object.keys(this.props.contacts), Object.keys(nextProps.contacts))) {
|
||||||
|
return this.setValues(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eq(Object.keys(this.props.contracts), Object.keys(nextProps.contracts))) {
|
||||||
|
return this.setValues(nextProps);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.store.values && this.store.values.length > 0) {
|
if (this.store.values && this.store.values.length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,8 @@ export default class AddressSelectStore {
|
|||||||
const contactsN = Object.keys(contacts).length;
|
const contactsN = Object.keys(contacts).length;
|
||||||
|
|
||||||
if (accountsN + contractsN + contactsN === 0) {
|
if (accountsN + contractsN + contactsN === 0) {
|
||||||
return;
|
this.initValues = [];
|
||||||
|
return this.handleChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initValues = [
|
this.initValues = [
|
||||||
|
@ -18,6 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { TextField } from 'material-ui';
|
import { TextField } from 'material-ui';
|
||||||
import { noop } from 'lodash';
|
import { noop } from 'lodash';
|
||||||
import keycode from 'keycode';
|
import keycode from 'keycode';
|
||||||
|
import localStore from 'store';
|
||||||
|
|
||||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||||
import { toString } from '~/util/messages';
|
import { toString } from '~/util/messages';
|
||||||
@ -223,7 +224,9 @@ export default class Input extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onChange = (event, value) => {
|
onChange = (event, value) => {
|
||||||
if (!this.props.allowPaste) {
|
const isDev = localStore.get('allYourBaseAreBelongToUs') || false;
|
||||||
|
|
||||||
|
if (!this.props.allowPaste && !isDev) {
|
||||||
if (value.length - this.state.value.length > 8) {
|
if (value.length - this.state.value.length > 8) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { pick } from 'lodash';
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ class InputAddressSelect extends Component {
|
|||||||
contracts: PropTypes.object.isRequired,
|
contracts: PropTypes.object.isRequired,
|
||||||
|
|
||||||
allowCopy: PropTypes.bool,
|
allowCopy: PropTypes.bool,
|
||||||
|
allowedValues: PropTypes.array,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
error: nodeOrStringProptype(),
|
error: nodeOrStringProptype(),
|
||||||
hint: nodeOrStringProptype(),
|
hint: nodeOrStringProptype(),
|
||||||
@ -38,16 +40,33 @@ class InputAddressSelect extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accounts, allowCopy, className, contacts, contracts, label, hint, error, value, onChange, readOnly } = this.props;
|
const { accounts, allowCopy, allowedValues, className, contacts, contracts, label, hint, error, value, onChange, readOnly } = this.props;
|
||||||
|
// Add the currently selected value to the list
|
||||||
|
// of allowed values, if any given
|
||||||
|
const nextAllowedValues = allowedValues
|
||||||
|
? [].concat(allowedValues, value || [])
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const filteredAccounts = nextAllowedValues
|
||||||
|
? pick(accounts, nextAllowedValues)
|
||||||
|
: accounts;
|
||||||
|
|
||||||
|
const filteredContacts = nextAllowedValues
|
||||||
|
? pick(contacts, nextAllowedValues)
|
||||||
|
: accounts;
|
||||||
|
|
||||||
|
const filteredContracts = nextAllowedValues
|
||||||
|
? pick(contracts, nextAllowedValues)
|
||||||
|
: accounts;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AddressSelect
|
<AddressSelect
|
||||||
allowCopy={ allowCopy }
|
allowCopy={ allowCopy }
|
||||||
allowInput
|
allowInput
|
||||||
accounts={ accounts }
|
accounts={ filteredAccounts }
|
||||||
className={ className }
|
className={ className }
|
||||||
contacts={ contacts }
|
contacts={ filteredContacts }
|
||||||
contracts={ contracts }
|
contracts={ filteredContracts }
|
||||||
error={ error }
|
error={ error }
|
||||||
hint={ hint }
|
hint={ hint }
|
||||||
label={ label }
|
label={ label }
|
||||||
|
@ -40,8 +40,8 @@ export default class TypedInput extends Component {
|
|||||||
PropTypes.string
|
PropTypes.string
|
||||||
]).isRequired,
|
]).isRequired,
|
||||||
|
|
||||||
accounts: PropTypes.object,
|
|
||||||
allowCopy: PropTypes.bool,
|
allowCopy: PropTypes.bool,
|
||||||
|
allowedValues: PropTypes.array,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
error: PropTypes.any,
|
error: PropTypes.any,
|
||||||
hint: nodeOrStringProptype(),
|
hint: nodeOrStringProptype(),
|
||||||
@ -97,7 +97,7 @@ export default class TypedInput extends Component {
|
|||||||
const { type } = param;
|
const { type } = param;
|
||||||
|
|
||||||
if (type === ABI_TYPES.ARRAY) {
|
if (type === ABI_TYPES.ARRAY) {
|
||||||
const { accounts, className, label } = this.props;
|
const { allowedValues, className, label } = this.props;
|
||||||
const { subtype, length } = param;
|
const { subtype, length } = param;
|
||||||
const value = this.getValue() || param.default;
|
const value = this.getValue() || param.default;
|
||||||
|
|
||||||
@ -113,8 +113,8 @@ export default class TypedInput extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TypedInput
|
<TypedInput
|
||||||
accounts={ accounts }
|
|
||||||
allowCopy={ allowCopy }
|
allowCopy={ allowCopy }
|
||||||
|
allowedValues={ allowedValues }
|
||||||
className={ className }
|
className={ className }
|
||||||
key={ `${subtype.type}_${index}` }
|
key={ `${subtype.type}_${index}` }
|
||||||
onChange={ onChange }
|
onChange={ onChange }
|
||||||
@ -340,13 +340,13 @@ export default class TypedInput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderAddress () {
|
renderAddress () {
|
||||||
const { accounts, allowCopy, className, label, error, hint, readOnly } = this.props;
|
const { allowCopy, allowedValues, className, label, error, hint, readOnly } = this.props;
|
||||||
const value = this.getValue();
|
const value = this.getValue();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InputAddressSelect
|
<InputAddressSelect
|
||||||
allowCopy={ allowCopy }
|
allowCopy={ allowCopy }
|
||||||
accounts={ accounts }
|
allowedValues={ allowedValues }
|
||||||
className={ className }
|
className={ className }
|
||||||
error={ error }
|
error={ error }
|
||||||
hint={ hint }
|
hint={ hint }
|
||||||
|
@ -78,13 +78,39 @@ export default class WalletsUtils {
|
|||||||
.delegateCall(api, walletContract.address, 'fetchTransactions', [ walletContract ])
|
.delegateCall(api, walletContract.address, 'fetchTransactions', [ walletContract ])
|
||||||
.then((transactions) => {
|
.then((transactions) => {
|
||||||
return transactions.sort((txA, txB) => {
|
return transactions.sort((txA, txB) => {
|
||||||
const comp = txB.blockNumber.comparedTo(txA.blockNumber);
|
const bnA = txA.blockNumber;
|
||||||
|
const bnB = txB.blockNumber;
|
||||||
|
|
||||||
|
if (!bnA) {
|
||||||
|
console.warn('could not find block number in transaction', txA);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bnB) {
|
||||||
|
console.warn('could not find block number in transaction', txB);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const comp = bnA.comparedTo(bnB);
|
||||||
|
|
||||||
if (comp !== 0) {
|
if (comp !== 0) {
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return txB.transactionIndex.comparedTo(txA.transactionIndex);
|
const txIdxA = txA.transactionIndex;
|
||||||
|
const txIdxB = txB.transactionIndex;
|
||||||
|
|
||||||
|
if (!txIdxA) {
|
||||||
|
console.warn('could not find transaction index in transaction', txA);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!txIdxB) {
|
||||||
|
console.warn('could not find transaction index in transaction', txB);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txIdxA.comparedTo(txIdxB);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,7 @@ export default class ConsensysWalletUtils {
|
|||||||
|
|
||||||
const transaction = {
|
const transaction = {
|
||||||
transactionHash: log.transactionHash,
|
transactionHash: log.transactionHash,
|
||||||
|
transactionIndex: log.transactionIndex,
|
||||||
blockNumber: log.blockNumber
|
blockNumber: log.blockNumber
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,27 +130,67 @@ export default class FoundationWalletUtils {
|
|||||||
.ConfirmationNeeded
|
.ConfirmationNeeded
|
||||||
.getAllLogs()
|
.getAllLogs()
|
||||||
.then((logs) => {
|
.then((logs) => {
|
||||||
return logs.map((log) => ({
|
return logs
|
||||||
initiator: log.params.initiator.value,
|
.filter((log) => {
|
||||||
to: log.params.to.value,
|
if (!log.blockNumber) {
|
||||||
data: log.params.data.value,
|
console.warn('got a log without blockNumber', log);
|
||||||
value: log.params.value.value,
|
return false;
|
||||||
operation: bytesToHex(log.params.operation.value),
|
}
|
||||||
transactionIndex: log.transactionIndex,
|
|
||||||
transactionHash: log.transactionHash,
|
if (!log.transactionIndex) {
|
||||||
blockNumber: log.blockNumber,
|
console.warn('got a log without transactionIndex', log);
|
||||||
confirmedBy: []
|
return false;
|
||||||
}));
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map((log) => ({
|
||||||
|
initiator: log.params.initiator.value,
|
||||||
|
to: log.params.to.value,
|
||||||
|
data: log.params.data.value,
|
||||||
|
value: log.params.value.value,
|
||||||
|
operation: bytesToHex(log.params.operation.value),
|
||||||
|
transactionIndex: log.transactionIndex,
|
||||||
|
transactionHash: log.transactionHash,
|
||||||
|
blockNumber: log.blockNumber,
|
||||||
|
confirmedBy: []
|
||||||
|
}));
|
||||||
})
|
})
|
||||||
.then((logs) => {
|
.then((logs) => {
|
||||||
return logs.sort((logA, logB) => {
|
return logs.sort((logA, logB) => {
|
||||||
const comp = logA.blockNumber.comparedTo(logB.blockNumber);
|
const bnA = logA.blockNumber;
|
||||||
|
const bnB = logA.blockNumber;
|
||||||
|
|
||||||
|
if (!bnA) {
|
||||||
|
console.warn('could not find block number in log', logA);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bnB) {
|
||||||
|
console.warn('could not find block number in log', logB);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const comp = bnA.comparedTo(bnB);
|
||||||
|
|
||||||
if (comp !== 0) {
|
if (comp !== 0) {
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return logA.transactionIndex.comparedTo(logB.transactionIndex);
|
const txIdxA = logA.transactionIndex;
|
||||||
|
const txIdxB = logB.transactionIndex;
|
||||||
|
|
||||||
|
if (!txIdxA) {
|
||||||
|
console.warn('could not find transaction index in log', logA);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!txIdxB) {
|
||||||
|
console.warn('could not find transaction index in log', logB);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return txIdxA.comparedTo(txIdxB);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then((pendingTxs) => {
|
.then((pendingTxs) => {
|
||||||
@ -205,40 +245,48 @@ export default class FoundationWalletUtils {
|
|||||||
] ]
|
] ]
|
||||||
})
|
})
|
||||||
.then((logs) => {
|
.then((logs) => {
|
||||||
const transactions = logs.map((log) => {
|
const transactions = logs
|
||||||
const signature = toHex(log.topics[0]);
|
.map((log) => {
|
||||||
|
const signature = toHex(log.topics[0]);
|
||||||
|
|
||||||
const value = log.params.value.value;
|
const value = log.params.value.value;
|
||||||
const from = signature === WalletSignatures.Deposit
|
const from = signature === WalletSignatures.Deposit
|
||||||
? log.params['_from'].value
|
? log.params['_from'].value
|
||||||
: walletContract.address;
|
: walletContract.address;
|
||||||
|
|
||||||
const to = signature === WalletSignatures.Deposit
|
const to = signature === WalletSignatures.Deposit
|
||||||
? walletContract.address
|
? walletContract.address
|
||||||
: log.params.to.value;
|
: log.params.to.value;
|
||||||
|
|
||||||
const transaction = {
|
const transaction = {
|
||||||
transactionHash: log.transactionHash,
|
transactionHash: log.transactionHash,
|
||||||
blockNumber: log.blockNumber,
|
transactionIndex: log.transactionIndex,
|
||||||
from, to, value
|
blockNumber: log.blockNumber,
|
||||||
};
|
from, to, value
|
||||||
|
};
|
||||||
|
|
||||||
if (log.params.created && log.params.created.value && !/^(0x)?0*$/.test(log.params.created.value)) {
|
if (!transaction.blockNumber) {
|
||||||
transaction.creates = log.params.created.value;
|
console.warn('log without block number', log);
|
||||||
delete transaction.to;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.params.operation) {
|
if (log.params.created && log.params.created.value && !/^(0x)?0*$/.test(log.params.created.value)) {
|
||||||
transaction.operation = bytesToHex(log.params.operation.value);
|
transaction.creates = log.params.created.value;
|
||||||
checkPendingOperation(api, log, transaction.operation);
|
delete transaction.to;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.params.data) {
|
if (log.params.operation) {
|
||||||
transaction.data = log.params.data.value;
|
transaction.operation = bytesToHex(log.params.operation.value);
|
||||||
}
|
checkPendingOperation(api, log, transaction.operation);
|
||||||
|
}
|
||||||
|
|
||||||
return transaction;
|
if (log.params.data) {
|
||||||
});
|
transaction.data = log.params.data.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return transaction;
|
||||||
|
})
|
||||||
|
.filter((tx) => tx);
|
||||||
|
|
||||||
return transactions;
|
return transactions;
|
||||||
});
|
});
|
||||||
|
@ -35,7 +35,6 @@ class InputQuery extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accountsInfo: PropTypes.object.isRequired,
|
|
||||||
contract: PropTypes.object.isRequired,
|
contract: PropTypes.object.isRequired,
|
||||||
inputs: arrayOrObjectProptype().isRequired,
|
inputs: arrayOrObjectProptype().isRequired,
|
||||||
outputs: arrayOrObjectProptype().isRequired,
|
outputs: arrayOrObjectProptype().isRequired,
|
||||||
@ -122,7 +121,7 @@ class InputQuery extends Component {
|
|||||||
|
|
||||||
renderResults () {
|
renderResults () {
|
||||||
const { results, isLoading } = this.state;
|
const { results, isLoading } = this.state;
|
||||||
const { accountsInfo, outputs } = this.props;
|
const { outputs } = this.props;
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
@ -143,7 +142,6 @@ class InputQuery extends Component {
|
|||||||
.map((out, index) => {
|
.map((out, index) => {
|
||||||
const input = (
|
const input = (
|
||||||
<TypedInput
|
<TypedInput
|
||||||
accounts={ accountsInfo }
|
|
||||||
allowCopy
|
allowCopy
|
||||||
isEth={ false }
|
isEth={ false }
|
||||||
param={ out.type }
|
param={ out.type }
|
||||||
|
@ -29,7 +29,6 @@ export default class Queries extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accountsInfo: PropTypes.object.isRequired,
|
|
||||||
contract: PropTypes.object,
|
contract: PropTypes.object,
|
||||||
values: PropTypes.object
|
values: PropTypes.object
|
||||||
}
|
}
|
||||||
@ -94,12 +93,11 @@ export default class Queries extends Component {
|
|||||||
|
|
||||||
renderInputQuery (fn) {
|
renderInputQuery (fn) {
|
||||||
const { abi, name, signature } = fn;
|
const { abi, name, signature } = fn;
|
||||||
const { accountsInfo, contract } = this.props;
|
const { contract } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.container } key={ fn.signature }>
|
<div className={ styles.container } key={ fn.signature }>
|
||||||
<InputQuery
|
<InputQuery
|
||||||
accountsInfo={ accountsInfo }
|
|
||||||
className={ styles.method }
|
className={ styles.method }
|
||||||
inputs={ abi.inputs }
|
inputs={ abi.inputs }
|
||||||
outputs={ abi.outputs }
|
outputs={ abi.outputs }
|
||||||
@ -144,13 +142,11 @@ export default class Queries extends Component {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { accountsInfo } = this.props;
|
|
||||||
const { name, type } = output;
|
const { name, type } = output;
|
||||||
const label = `${name ? `${name}: ` : ''}${type}`;
|
const label = `${name ? `${name}: ` : ''}${type}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TypedInput
|
<TypedInput
|
||||||
accounts={ accountsInfo }
|
|
||||||
allowCopy
|
allowCopy
|
||||||
key={ key }
|
key={ key }
|
||||||
isEth={ false }
|
isEth={ false }
|
||||||
|
@ -45,7 +45,6 @@ class Contract extends Component {
|
|||||||
setVisibleAccounts: PropTypes.func.isRequired,
|
setVisibleAccounts: PropTypes.func.isRequired,
|
||||||
|
|
||||||
accounts: PropTypes.object,
|
accounts: PropTypes.object,
|
||||||
accountsInfo: PropTypes.object,
|
|
||||||
contracts: PropTypes.object,
|
contracts: PropTypes.object,
|
||||||
netVersion: PropTypes.string.isRequired,
|
netVersion: PropTypes.string.isRequired,
|
||||||
params: PropTypes.object
|
params: PropTypes.object
|
||||||
@ -128,7 +127,7 @@ class Contract extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountsInfo, contracts, netVersion, params } = this.props;
|
const { contracts, netVersion, params } = this.props;
|
||||||
const { allEvents, contract, queryValues, loadingEvents } = this.state;
|
const { allEvents, contract, queryValues, loadingEvents } = this.state;
|
||||||
const account = contracts[params.address];
|
const account = contracts[params.address];
|
||||||
|
|
||||||
@ -150,7 +149,6 @@ class Contract extends Component {
|
|||||||
{ this.renderBlockNumber(account.meta) }
|
{ this.renderBlockNumber(account.meta) }
|
||||||
</Header>
|
</Header>
|
||||||
<Queries
|
<Queries
|
||||||
accountsInfo={ accountsInfo }
|
|
||||||
contract={ contract }
|
contract={ contract }
|
||||||
values={ queryValues }
|
values={ queryValues }
|
||||||
/>
|
/>
|
||||||
@ -530,12 +528,11 @@ class Contract extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const { accounts, accountsInfo, contracts } = state.personal;
|
const { accounts, contracts } = state.personal;
|
||||||
const { netVersion } = state.nodeStatus;
|
const { netVersion } = state.nodeStatus;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accounts,
|
accounts,
|
||||||
accountsInfo,
|
|
||||||
contracts,
|
contracts,
|
||||||
netVersion
|
netVersion
|
||||||
};
|
};
|
||||||
|
@ -116,7 +116,6 @@ section "install"
|
|||||||
# Firewall exception rules
|
# Firewall exception rules
|
||||||
SimpleFC::AdvAddRule "Parity incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" 30303 "" "" ""
|
SimpleFC::AdvAddRule "Parity incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" 30303 "" "" ""
|
||||||
SimpleFC::AdvAddRule "Parity outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" ""
|
SimpleFC::AdvAddRule "Parity outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" ""
|
||||||
SimpleFC::AdvAddRule "Parity web queries (TCP:80)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 80 "" ""
|
|
||||||
SimpleFC::AdvAddRule "Parity UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" ""
|
SimpleFC::AdvAddRule "Parity UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" ""
|
||||||
|
|
||||||
# Registry information for add/remove programs
|
# Registry information for add/remove programs
|
||||||
|
@ -3,8 +3,18 @@ Description=Parity Daemon
|
|||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
EnvironmentFile=-%h/.parity/parity.conf
|
# run as root, set base_path in config.toml
|
||||||
ExecStart=/usr/bin/parity $ARGS
|
ExecStart=/usr/bin/parity --config /etc/parity/config.toml
|
||||||
|
# To run as user, comment out above and uncomment below, fill in user and group
|
||||||
|
# picks up users default config.toml in $HOME/.local/.share/io.parity.ethereum/
|
||||||
|
# User=username
|
||||||
|
# Group=groupname
|
||||||
|
# ExecStart=/usr/bin/parity
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
# Specifies which signal to use when killing a service. Defaults to SIGTERM.
|
||||||
|
# SIGHUP gives parity time to exit cleanly before SIGKILL (default 90s)
|
||||||
|
KillSignal=SIGHUP
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
|
Loading…
Reference in New Issue
Block a user