diff --git a/js/src/index.js b/js/src/index.js index 28abe953b..d1f9ac580 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -36,7 +36,7 @@ import ContextProvider from '~/ui/ContextProvider'; import muiTheme from '~/ui/Theme'; import MainApplication from './main'; -import { patchApi } from '~/util/tx'; +import { loadSender, patchApi } from '~/util/tx'; import { setApi } from '~/redux/providers/apiActions'; import './environment'; @@ -66,6 +66,7 @@ if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) { const api = new SecureApi(`${urlScheme}${parityUrl}`, token); patchApi(api); +loadSender(api); ContractInstances.create(api); const store = initStore(api, hashHistory); diff --git a/js/src/modals/CreateWallet/createWallet.spec.js b/js/src/modals/CreateWallet/createWallet.spec.js index 45c9776e1..e38174b81 100644 --- a/js/src/modals/CreateWallet/createWallet.spec.js +++ b/js/src/modals/CreateWallet/createWallet.spec.js @@ -27,7 +27,11 @@ let component; let onClose; function createApi () { - api = {}; + api = { + parity: { + getNewDappsDefaultAddress: sinon.stub().resolves('') + } + }; return api; } diff --git a/js/src/modals/CreateWallet/createWalletStore.js b/js/src/modals/CreateWallet/createWalletStore.js index 740aa8f17..dd243f179 100644 --- a/js/src/modals/CreateWallet/createWalletStore.js +++ b/js/src/modals/CreateWallet/createWalletStore.js @@ -26,7 +26,7 @@ import { wallet as walletCode, walletLibrary as walletLibraryCode, walletLibrary import { validateUint, validateAddress, validateName } from '~/util/validation'; import { toWei } from '~/api/util/wei'; -import { deploy } from '~/util/tx'; +import { deploy, getSender, loadSender, setSender } from '~/util/tx'; import WalletsUtils from '~/util/wallets'; const STEPS = { @@ -120,10 +120,17 @@ export default class CreateWalletStore { this.api = api; this.step = this.stepsKeys[0]; - this.wallet.account = Object.values(accounts)[0].address; + this.wallet.account = getSender() || Object.values(accounts)[0].address; this.validateWallet(this.wallet); this.onClose = onClose; this.onSetRequest = onSetRequest; + + loadSender(this.api) + .then((defaultAccount) => { + if (defaultAccount !== this.wallet.account) { + this.onChange({ account: defaultAccount }); + } + }); } @action onTypeChange = (type) => { @@ -221,6 +228,7 @@ export default class CreateWalletStore { const contract = this.api.newContract(walletAbi); + setSender(account); this.wallet = this.getWalletWithMeta(this.wallet); this.onClose(); return deploy(contract, options, [ owners, required, daylimit ]) diff --git a/js/src/modals/DeployContract/deployContract.js b/js/src/modals/DeployContract/deployContract.js index 0f5b4e1d8..a5d6c6b34 100644 --- a/js/src/modals/DeployContract/deployContract.js +++ b/js/src/modals/DeployContract/deployContract.js @@ -24,7 +24,7 @@ import { bindActionCreators } from 'redux'; import { Button, GasPriceEditor, IdentityIcon, Portal, Warning } from '~/ui'; import { CancelIcon } from '~/ui/Icons'; import { ERRORS, validateAbi, validateCode, validateName, validatePositiveNumber } from '~/util/validation'; -import { deploy, deployEstimateGas } from '~/util/tx'; +import { deploy, deployEstimateGas, getSender, loadSender, setSender } from '~/util/tx'; import { setRequest } from '~/redux/providers/requestsActions'; import DetailsStep from './DetailsStep'; @@ -94,7 +94,7 @@ class DeployContract extends Component { description: '', descriptionError: null, extras: false, - fromAddress: Object.keys(this.props.accounts)[0], + fromAddress: getSender() || Object.keys(this.props.accounts)[0], fromAddressError: null, name: '', nameError: ERRORS.invalidName, @@ -110,6 +110,13 @@ class DeployContract extends Component { if (abi && code) { this.setState({ abi, code }); } + + loadSender(this.context.api) + .then((defaultAccount) => { + if (defaultAccount !== this.state.fromAddress) { + this.setState({ fromAddress: defaultAccount }); + } + }); } componentWillReceiveProps (nextProps) { @@ -467,6 +474,7 @@ class DeployContract extends Component { const contract = api.newContract(abiParsed); + setSender(fromAddress); this.onClose(); deploy(contract, options, params, true) .then((requestId) => { diff --git a/js/src/modals/ExecuteContract/executeContract.js b/js/src/modals/ExecuteContract/executeContract.js index e0566f7df..0f648dece 100644 --- a/js/src/modals/ExecuteContract/executeContract.js +++ b/js/src/modals/ExecuteContract/executeContract.js @@ -25,6 +25,7 @@ import { CancelIcon, NextIcon, PrevIcon } from '~/ui/Icons'; import { MAX_GAS_ESTIMATION } from '~/util/constants'; import { validateAddress, validateUint } from '~/util/validation'; import { parseAbiType } from '~/util/abi'; +import { setSender } from '~/util/tx'; import AdvancedStep from './AdvancedStep'; import DetailsStep from './DetailsStep'; @@ -307,6 +308,7 @@ class ExecuteContract extends Component { value: api.util.toWei(amount || 0) }); + setSender(fromAddress); func.postTransaction(options, values); this.onClose(); } diff --git a/js/src/util/tx.js b/js/src/util/tx.js index b56fc8b1f..9ab8b6599 100644 --- a/js/src/util/tx.js +++ b/js/src/util/tx.js @@ -16,6 +16,38 @@ import WalletsUtils from '~/util/wallets'; +/** + * The sender is by default (when the UI loads) the + * default dapp address. It can then be modified when + * sending transactions.... + */ +let currentSender = ''; +let hasCurrentSenderChanged = false; + +export function getSender () { + currentSender; +} + +export function loadSender (api) { + // If the current sender has been changed + // then don't bother checking changes of the + // default sender + if (hasCurrentSenderChanged) { + return Promise.resolve(currentSender); + } + + return api.parity.getNewDappsDefaultAddress() + .then((defaultAccount) => { + currentSender = defaultAccount; + return defaultAccount; + }); +} + +export function setSender (sender) { + currentSender = sender; + hasCurrentSenderChanged = true; +} + export function trackRequest (api, options, statusCallback) { const { requestId, transactionHash } = options; const txHashPromise = transactionHash diff --git a/js/src/views/Contract/contract.js b/js/src/views/Contract/contract.js index cc6b35d2b..b362d0d0d 100644 --- a/js/src/views/Contract/contract.js +++ b/js/src/views/Contract/contract.js @@ -26,6 +26,7 @@ import { setVisibleAccounts } from '~/redux/providers/personalActions'; import { Actionbar, Button, Page, Portal } from '~/ui'; import { CancelIcon, DeleteIcon, EditIcon, PlayIcon, VisibleIcon } from '~/ui/Icons'; import Editor from '~/ui/Editor'; +import { getSender, loadSender } from '~/util/tx'; import Header from '../Account/Header'; import Delete from '../Address/Delete'; @@ -52,7 +53,7 @@ class Contract extends Component { state = { contract: null, - fromAddress: '', + fromAddress: getSender(), showDeleteDialog: false, showEditDialog: false, showExecuteDialog: false, @@ -76,6 +77,13 @@ class Contract extends Component { api .subscribe('eth_blockNumber', this.queryContract) .then(blockSubscriptionId => this.setState({ blockSubscriptionId })); + + loadSender(api) + .then((defaultAccount) => { + if (defaultAccount !== this.state.fromAddress) { + this.onFromAddressChange(null, defaultAccount); + } + }); } componentWillReceiveProps (nextProps) {