diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index 05753a2..16bdeff 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -103,13 +103,14 @@ export function toggleSendReceiveCoinFormsState() { } } -export function triggerToaster(message, title, _type, autoClose = true) { +export function triggerToaster(message, title, _type, autoClose = true, className) { return { type: ADD_TOASTER_MESSAGE, message, title, _type, autoClose, + className, } } diff --git a/react/src/actions/actions/addCoin.js b/react/src/actions/actions/addCoin.js index de89372..d102880 100644 --- a/react/src/actions/actions/addCoin.js +++ b/react/src/actions/actions/addCoin.js @@ -70,12 +70,22 @@ export function shepherdElectrumAuth(seed) { 'Error', 'error' ) - ) + ); }) .then(response => response.json()) .then(json => { - dispatch(activeHandle()); - dispatch(shepherdElectrumCoins()); + if (json.msg !== 'error') { + dispatch(activeHandle()); + dispatch(shepherdElectrumCoins()); + } else { + dispatch( + triggerToaster( + 'Icorrect WIF key format', + 'Error', + 'error' + ) + ); + } }); } } @@ -96,7 +106,7 @@ export function shepherdElectrumAddCoin(coin) { 'Error', 'error' ) - ) + ); }) .then(response => response.json()) .then(json => { @@ -140,7 +150,7 @@ export function shepherdHerd(coin, mode, path, startupParams) { '-server', `-ac_name=${coin}`, '-addnode=78.47.196.146', - ] + ], }; if (coin === 'ZEC') { @@ -149,7 +159,7 @@ export function shepherdHerd(coin, mode, path, startupParams) { 'ac_options': [ '-daemon=0', '-server=1', - ] + ], }; } @@ -159,7 +169,7 @@ export function shepherdHerd(coin, mode, path, startupParams) { 'ac_options': [ '-daemon=0', '-addnode=78.47.196.146', - ] + ], }; } @@ -268,10 +278,11 @@ export function addCoinResult(coin, mode) { ) ); dispatch(toggleAddcoinModal(false, false)); + if (Number(mode) === 0) { dispatch(activeHandle()); dispatch(shepherdElectrumCoins()); - dispatch(getDexCoins()); + dispatch(getDexCoins()); setTimeout(() => { dispatch(activeHandle()); @@ -372,7 +383,7 @@ export function shepherdGetConfig(coin, mode, startupParams) { startupParams ) ) - ) + ); } } else { return dispatch => { diff --git a/react/src/actions/actions/cli.js b/react/src/actions/actions/cli.js index 98e9202..735c30c 100644 --- a/react/src/actions/actions/cli.js +++ b/react/src/actions/actions/cli.js @@ -29,7 +29,7 @@ export function shepherdCliPromise(mode, chain, cmd) { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -59,7 +59,7 @@ export function shepherdCli(mode, chain, cmd) { ); }) .then(response => response.json()) - .then(json => dispatch(cliResponseState(json))) + .then(json => dispatch(cliResponseState(json))); } } diff --git a/react/src/actions/actions/coinList.js b/react/src/actions/actions/coinList.js index a2cf8d3..a4d73c6 100644 --- a/react/src/actions/actions/coinList.js +++ b/react/src/actions/actions/coinList.js @@ -23,7 +23,7 @@ export function shepherdElectrumLock() { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -47,7 +47,7 @@ export function shepherdElectrumLogout() { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -71,7 +71,7 @@ export function shepherdStopCoind(coin) { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -111,7 +111,7 @@ export function shepherdRemoveCoin(coin, mode) { ) ); } - }) + }); }); } @@ -134,7 +134,7 @@ export function shepherdGetCoinList() { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -158,7 +158,7 @@ export function shepherdPostCoinList(data) { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -181,6 +181,6 @@ export function shepherdClearCoindFolder(coin, keepWalletDat) { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } \ No newline at end of file diff --git a/react/src/actions/actions/electrum.js b/react/src/actions/actions/electrum.js index 915eede..d41df99 100644 --- a/react/src/actions/actions/electrum.js +++ b/react/src/actions/actions/electrum.js @@ -17,7 +17,7 @@ export function shepherdElectrumSetServer(coin, address, port) { method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -42,7 +42,7 @@ export function shepherdElectrumCheckServerConnection(address, port) { method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -56,11 +56,7 @@ export function shepherdElectrumCheckServerConnection(address, port) { }) .then(response => response.json()) .then(json => { - if (!json.result) { - resolve('error'); - } else { - resolve(json); - } + resolve(!json.result ? 'error' : json); }); }); } @@ -90,11 +86,7 @@ export function shepherdElectrumKeys(seed) { }) .then(response => response.json()) .then(json => { - if (!json.result) { - resolve('error'); - } else { - resolve(json); - } + resolve(!json.result ? 'error' : json); }); }); } @@ -105,7 +97,7 @@ export function shepherdElectrumBalance(coin, address) { method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -137,7 +129,7 @@ export function shepherdElectrumTransactions(coin, address) { method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -178,7 +170,7 @@ export function shepherdElectrumCoins() { method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -211,7 +203,7 @@ export function shepherdElectrumSend(coin, value, sendToAddress, changeAddress) method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -225,11 +217,7 @@ export function shepherdElectrumSend(coin, value, sendToAddress, changeAddress) }) .then(response => response.json()) .then(json => { - if (json.msg === 'error') { - dispatch(sendToAddressState(json)); - } else { - dispatch(sendToAddressState(json.result)); - } + dispatch(sendToAddressState(json.msg === 'error' ? json : json.result)); }); } } @@ -240,7 +228,7 @@ export function shepherdElectrumSendPromise(coin, value, sendToAddress, changeAd method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -265,7 +253,7 @@ export function shepherdElectrumSendPreflight(coin, value, sendToAddress, change method: 'GET', headers: { 'Content-Type': 'application/json', - } + }, }) .catch((error) => { console.log(error); @@ -304,11 +292,7 @@ export function shepherdElectrumListunspent(coin, address) { }) .then(response => response.json()) .then(json => { - if (!json.result) { - resolve('error'); - } else { - resolve(json); - } + resolve(!json.result ? 'error' : json); }); }); } diff --git a/react/src/actions/actions/getTxDetails.js b/react/src/actions/actions/getTxDetails.js index 54df785..1a7e8f1 100644 --- a/react/src/actions/actions/getTxDetails.js +++ b/react/src/actions/actions/getTxDetails.js @@ -11,6 +11,7 @@ export function getTxDetails(coin, txid, type) { params: [ txid ], + rpc2cli: Config.rpc2cli, }; if (type === 'raw') { @@ -22,6 +23,7 @@ export function getTxDetails(coin, txid, type) { txid, 1 ], + rpc2cli: Config.rpc2cli, }; } @@ -47,6 +49,6 @@ export function getTxDetails(coin, txid, type) { .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); - }) + }); }); } \ No newline at end of file diff --git a/react/src/actions/actions/interest.js b/react/src/actions/actions/interest.js index f784363..e62b3e0 100644 --- a/react/src/actions/actions/interest.js +++ b/react/src/actions/actions/interest.js @@ -8,6 +8,7 @@ export function getListUnspent(coin) { mode: null, chain: coin, cmd: 'listunspent', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -49,7 +50,7 @@ export function getListUnspent(coin) { } resolve(json.result ? json.result : json); - }) + }); }); } @@ -63,6 +64,7 @@ export function getRawTransaction(coin, txid) { txid, 1 ], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -90,6 +92,6 @@ export function getRawTransaction(coin, txid) { .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); - }) + }); }); } \ No newline at end of file diff --git a/react/src/actions/actions/jumblr.js b/react/src/actions/actions/jumblr.js index 1fa4e15..ee8d55c 100644 --- a/react/src/actions/actions/jumblr.js +++ b/react/src/actions/actions/jumblr.js @@ -1,16 +1,17 @@ import { triggerToaster, - getNewKMDAddresses + getNewKMDAddresses, } from '../actionCreators'; import Config from '../../config'; import Store from '../../store'; -function getNewAddress(coin) { // TODO: remove(?) +function getNewAddress(coin) { return new Promise((resolve, reject) => { const payload = { mode: null, chain: coin, cmd: 'getnewaddress', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -38,7 +39,7 @@ function getNewAddress(coin) { // TODO: remove(?) .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); - }) + }); }); } @@ -49,6 +50,7 @@ export function setJumblrAddress(coin, type, address) { chain: coin, cmd: type === 'deposit' ? 'jumblr_deposit' : 'jumblr_secret', params: [address], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -87,6 +89,7 @@ export function pauseJumblr(coin) { chain: coin, cmd: 'jumblr_pause', params: [], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -125,6 +128,7 @@ export function resumeJumblr(coin) { chain: coin, cmd: 'jumblr_resume', params: [], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -163,6 +167,7 @@ function dumpPrivkey(coin, key) { chain: coin, cmd: 'dumpprivkey', params: [key], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -190,7 +195,7 @@ function dumpPrivkey(coin, key) { .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); - }) + }); }); } @@ -205,6 +210,7 @@ export function importPrivkey(coin, key, rescan = false) { '', rescan ], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -232,6 +238,6 @@ export function importPrivkey(coin, key, rescan = false) { .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); - }) + }); }); } \ No newline at end of file diff --git a/react/src/actions/actions/nativeDashboardUpdate.js b/react/src/actions/actions/nativeDashboardUpdate.js index 171554b..5aa52dc 100644 --- a/react/src/actions/actions/nativeDashboardUpdate.js +++ b/react/src/actions/actions/nativeDashboardUpdate.js @@ -9,7 +9,10 @@ export function getDashboardUpdate(coin, activeCoinProps) { headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ coin: coin }), + body: JSON.stringify({ + coin: coin, + rpc2cli: Config.rpc2cli, + }), }; return fetch( @@ -38,7 +41,7 @@ export function getDashboardUpdate(coin, activeCoinProps) { dispatch(getDashboardUpdateState(json, coin)); }, 100); } - }) + }); } } @@ -80,7 +83,7 @@ export function getDashboardUpdateState(json, coin, fakeResponse) { txhistory: _listtransactions, balance: { transparent: json.result.getbalance.result, - total: json.result.getbalance.result + total: json.result.getbalance.result, }, addresses: json.result.addresses, coin: coin, @@ -89,13 +92,14 @@ export function getDashboardUpdateState(json, coin, fakeResponse) { }; } else { // calc transparent balance properly + const _addresses = json.result.addresses; let _tbalance = 0; - if (json.result.addresses && - json.result.addresses.public && - json.result.addresses.public.length) { - for (let i = 0; i < json.result.addresses.public.length; i++) { - _tbalance += json.result.addresses.public[i].spendable; + if (_addresses && + _addresses.public && + _addresses.public.length) { + for (let i = 0; i < _addresses.public.length; i++) { + _tbalance += _addresses.public[i].spendable; } } diff --git a/react/src/actions/actions/nativeNetwork.js b/react/src/actions/actions/nativeNetwork.js index 2141b2e..7d6b53c 100644 --- a/react/src/actions/actions/nativeNetwork.js +++ b/react/src/actions/actions/nativeNetwork.js @@ -12,6 +12,7 @@ export function getNativePeers(coin) { mode: null, chain: coin, cmd: 'getpeerinfo', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -40,7 +41,7 @@ export function getNativePeers(coin) { .then(json => { json = json.result; dispatch(getNativePeersState(json)); - }) + }); }; } @@ -50,6 +51,7 @@ export function getNativeNettotals(coin) { mode: null, chain: coin, cmd: 'getnettotals', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -78,7 +80,7 @@ export function getNativeNettotals(coin) { .then(json => { json = json.result; dispatch(getNativeNettotalsState(json)); - }) + }); }; } diff --git a/react/src/actions/actions/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js index c5d345a..b7bb1e0 100644 --- a/react/src/actions/actions/nativeNewAddress.js +++ b/react/src/actions/actions/nativeNewAddress.js @@ -11,6 +11,7 @@ export function getNewKMDAddresses(coin, pubpriv, mode) { mode: null, chain: coin, cmd: pubpriv === 'public' ? 'getnewaddress' : 'z_getnewaddress', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index edf1f44..1c1af5d 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -1,6 +1,6 @@ import { DASHBOARD_ACTIVE_COIN_NATIVE_OPIDS, - DASHBOARD_ACTIVE_COIN_SENDTO + DASHBOARD_ACTIVE_COIN_SENDTO, } from '../storeType'; import { translate } from '../../translate/translate'; import { triggerToaster } from '../actionCreators'; @@ -23,6 +23,7 @@ export function sendNativeTx(coin, _payload) { mode: null, chain: coin, cmd: _apiMethod, + rpc2cli: Config.rpc2cli, params: (_payload.addressType === 'public' && _payload.sendTo.length !== 95) || !_payload.sendFrom ? (_payload.substractFee ? @@ -77,8 +78,8 @@ export function sendNativeTx(coin, _payload) { }) .then((json) => { if (json.indexOf('"code":') > -1) { - const _message = json.substring( - `${json.indexOf('"message":"')}11`, + let _message = json.substring( + `${json.indexOf('"message":"') + 11}`, json.indexOf('"},"id":"jl777"') ); @@ -100,6 +101,10 @@ export function sendNativeTx(coin, _payload) { ) ); } else { + if (Config.rpc2cli) { + _message = JSON.parse(json).error.message; + } + dispatch( triggerToaster( _message, @@ -118,7 +123,7 @@ export function sendNativeTx(coin, _payload) { ) ); } - }) + }); } } @@ -136,6 +141,7 @@ export function getKMDOPID(opid, coin) { mode: null, chain: coin, cmd: 'z_getoperationstatus', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -164,7 +170,7 @@ export function getKMDOPID(opid, coin) { .then(json => { json = json.result; dispatch(getKMDOPIDState(json)); - }) + }); }; } @@ -174,6 +180,7 @@ export function sendToAddressPromise(coin, address, amount) { mode: null, chain: coin, cmd: 'sendtoaddress', + rpc2cli: Config.rpc2cli, params: [ address, amount, @@ -233,6 +240,7 @@ export function validateAddressPromise(coin, address) { chain: coin, cmd: 'validateaddress', params: [ address ], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index e0bc91d..42e0e3c 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -1,6 +1,6 @@ import { SYNCING_NATIVE_MODE, - DASHBOARD_ACTIVE_COIN_GETINFO_FAILURE + DASHBOARD_ACTIVE_COIN_GETINFO_FAILURE, } from '../storeType'; import { triggerToaster, @@ -97,6 +97,7 @@ export function getSyncInfoNative(coin, skipDebug, skipRemote, suppressErrors) { mode: null, chain: coin, cmd: 'getinfo', + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { method: 'POST', @@ -197,7 +198,7 @@ export function getSyncInfoNative(coin, skipDebug, skipRemote, suppressErrors) { ); } } - }) + }); } } @@ -206,6 +207,7 @@ export function getBlockTemplate(_json, coin) { mode: null, chain: coin, cmd: 'getblocktemplate', + rpc2cli: Config.rpc2cli, }; return dispatch => { @@ -262,7 +264,7 @@ export function getBlockTemplate(_json, coin) { ); } } - }) + }); } } @@ -338,6 +340,6 @@ export function getDebugLogProgress(_json, coin) { ) ); } - }) + }); } } \ No newline at end of file diff --git a/react/src/actions/actions/pin.js b/react/src/actions/actions/pin.js index dcc4938..4eabdaf 100644 --- a/react/src/actions/actions/pin.js +++ b/react/src/actions/actions/pin.js @@ -40,7 +40,7 @@ export function encryptPassphrase(passphrase, key, pubKey) { 'success' ) ); - }) + }); } } @@ -71,7 +71,7 @@ export function loginWithPin(key, pubKey) { .then(response => response.json()) .then(json => { dispatch(iguanaWalletPassphrase(json.result)); - }) + }); } } @@ -105,6 +105,6 @@ export function loadPinList() { dispatch( getPinList(json.result) ); - }) + }); } } \ No newline at end of file diff --git a/react/src/actions/actions/settings.js b/react/src/actions/actions/settings.js index d790180..80eb2b8 100644 --- a/react/src/actions/actions/settings.js +++ b/react/src/actions/actions/settings.js @@ -36,7 +36,7 @@ export function getAppInfo() { ); }) .then(response => response.json()) - .then(json => dispatch(getAppInfoState(json))) + .then(json => dispatch(getAppInfoState(json))); } } @@ -125,7 +125,7 @@ export function importPrivKey(wifKey) { error: 'privkey already in wallet', }, dispatch)); console.log('parsing failed', ex); - }) + }); } } @@ -167,7 +167,7 @@ export function getDebugLog(target, linesCount, acName) { ); }) .then(response => response.json()) - .then(json => dispatch(getDebugLogState(json))) + .then(json => dispatch(getDebugLogState(json))); } } @@ -197,7 +197,7 @@ export function getPeersList(coin) { .then(response => response.json()) .then(json => { dispatch(getPeersListState(json, dispatch)); - }) + }); } } @@ -290,7 +290,7 @@ export function addPeerNode(coin, ip) { .then(response => response.json()) .then(json => { dispatch(addPeerNodeState(json, dispatch)); - }) + }); } } @@ -323,7 +323,7 @@ export function saveAppConfig(_payload) { 'success' ) ); - }) + }); } } @@ -353,7 +353,7 @@ export function getAppConfig() { ); }) .then(response => response.json()) - .then(json => dispatch(getAppConfigState(json))) + .then(json => dispatch(getAppConfigState(json))); } } @@ -385,7 +385,7 @@ export function resetAppConfig() { 'success' ) ); - }) + }); } } @@ -449,7 +449,8 @@ export function dumpPrivKey(coin, address, isZaddr) { mode: null, chain: coin, cmd: isZaddr ? 'z_exportkey' : 'dumpprivkey', - params: [ address ] + params: [ address ], + rpc2cli: Config.rpc2cli, }; const _fetchConfig = { @@ -477,6 +478,45 @@ export function dumpPrivKey(coin, address, isZaddr) { .then(response => response.json()) .then(json => { resolve(json.result ? json.result : json); + }); + }); +} + +export function validateAddress(coin, address, isZaddr) { + return new Promise((resolve, reject) => { + const payload = { + mode: null, + chain: coin, + cmd: isZaddr ? 'z_validateaddress' : 'validateaddress', + params: [ address ], + rpc2cli: Config.rpc2cli, + }; + + const _fetchConfig = { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ 'payload': payload }), + }; + + fetch( + `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`, + _fetchConfig + ) + .catch(function(error) { + console.log(error); + Store.dispatch( + triggerToaster( + 'validateAddress', + 'Error', + 'error' + ) + ); }) + .then(response => response.json()) + .then(json => { + resolve(json.result ? json.result : json); + }); }); } \ No newline at end of file diff --git a/react/src/actions/actions/update.js b/react/src/actions/actions/update.js index f392fb1..d85dc7a 100644 --- a/react/src/actions/actions/update.js +++ b/react/src/actions/actions/update.js @@ -21,7 +21,7 @@ export function checkForUpdateUIPromise() { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -44,7 +44,7 @@ export function updateUIPromise() { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } @@ -67,6 +67,6 @@ export function downloadZCashParamsPromise(dloption) { ); }) .then(response => response.json()) - .then(json => resolve(json)) + .then(json => resolve(json)); }); } diff --git a/react/src/actions/actions/walletAuth.js b/react/src/actions/actions/walletAuth.js index 7e8f487..c071027 100644 --- a/react/src/actions/actions/walletAuth.js +++ b/react/src/actions/actions/walletAuth.js @@ -1,6 +1,6 @@ import { LOGIN, - ACTIVE_HANDLE + ACTIVE_HANDLE, } from '../storeType'; import { translate } from '../../translate/translate'; import Config from '../../config'; diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js index 0031f28..8acb29f 100644 --- a/react/src/components/dashboard/coinTile/coinTileItem.js +++ b/react/src/components/dashboard/coinTile/coinTileItem.js @@ -46,8 +46,55 @@ class CoinTileItem extends React.Component { activeCoin: null, activeCoinMode: null, propsUpdatedCounter: 0, + toggledCoinMenu: null, }; this.autoSetActiveCoin = this.autoSetActiveCoin.bind(this); + this.toggleCoinMenu = this.toggleCoinMenu.bind(this); + this.handleClickOutside = this.handleClickOutside.bind(this); + } + + componentWillMount() { + const appConfig = mainWindow.appConfig; + + if (!this.props.ActiveCoin.coin) { + this.autoSetActiveCoin(); + } + + this.setState({ + appConfig, + }); + + document.addEventListener( + 'click', + this.handleClickOutside, + false + ); + } + + componentWillUnmount() { + document.removeEventListener( + 'click', + this.handleClickOutside, + false + ); + } + + handleClickOutside(e) { + if (e && + e.srcElement && + e.srcElement.offsetParent && + e.srcElement.offsetParent.className.indexOf('dropdown') === -1 && + (e.srcElement.offsetParent && e.srcElement.offsetParent.className.indexOf('dropdown') === -1)) { + this.setState({ + toggledCoinMenu: e.srcElement.className.indexOf('coin-tile-context-menu-trigger') === -1 ? null : this.state.toggledCoinMenu, + }); + } + } + + toggleCoinMenu(coin) { + this.setState({ + toggledCoinMenu: this.state.toggledCoinMenu === coin ? null : coin, + }); } openCoindDownModal() { @@ -130,19 +177,11 @@ class CoinTileItem extends React.Component { } } - componentWillMount() { - if (!this.props.ActiveCoin.coin) { - this.autoSetActiveCoin(); - } - - const appConfig = mainWindow.appConfig; - + removeCoin(coin, mode) { this.setState({ - appConfig, + toggledCoinMenu: null, }); - } - removeCoin(coin, mode) { shepherdRemoveCoin(coin, mode) .then((res) => { Store.dispatch( @@ -163,6 +202,10 @@ class CoinTileItem extends React.Component { } stopCoind(coin) { + this.setState({ + toggledCoinMenu: null, + }); + shepherdStopCoind(coin) .then((res) => { if (res.msg === 'error') { diff --git a/react/src/components/dashboard/coinTile/coinTileItem.render.js b/react/src/components/dashboard/coinTile/coinTileItem.render.js index e281b1d..2028a83 100644 --- a/react/src/components/dashboard/coinTile/coinTileItem.render.js +++ b/react/src/components/dashboard/coinTile/coinTileItem.render.js @@ -24,17 +24,41 @@ const CoinTileItemRender = function() { - { this.renderStopCoinButton() && + + { this.state.toggledCoinMenu && + this.state.toggledCoinMenu === item.coin && +
+ +
+ } + { /*this.renderStopCoinButton() && this.stopCoind(item.coin, item.mode) } title={ translate('DASHBOARD.STOP') } - className="icon fa-stop-circle coind-stop-icon"> + className="icon fa-stop-circle coind-stop-icon">*/ } - { this.renderRemoveCoinButton() && + { /*this.renderRemoveCoinButton() && this.removeCoin(item.coin, item.mode) } title={ translate('DASHBOARD.REMOVE') } - className={ 'icon fa-plus-circle coind-remove-icon' + (item.mode === 'spv' ? ' coind-remove-icon-spv' : '') }> + className={ 'icon fa-plus-circle coind-remove-icon' + (item.mode === 'spv' ? ' coind-remove-icon-spv' : '') }>*/ } { this.props.Dashboard && this.props.Dashboard.electrumCoins && diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 3a18ed6..c4efcd6 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -5,6 +5,8 @@ import { getNewKMDAddresses, dumpPrivKey, copyString, + triggerToaster, + validateAddress, } from '../../../actions/actionCreators'; import Store from '../../../store'; import { @@ -33,6 +35,7 @@ class ReceiveCoin extends React.Component { this.ReceiveCoinTableRender = _ReceiveCoinTableRender.bind(this); this.toggleAddressMenu = this.toggleAddressMenu.bind(this); this.toggleIsMine = this.toggleIsMine.bind(this); + this.validateCoinAddress = this.validateCoinAddress.bind(this); } toggleAddressMenu(address) { @@ -61,6 +64,28 @@ class ReceiveCoin extends React.Component { ); } + validateCoinAddress(address, isZaddr) { + this.toggleAddressMenu(address); + validateAddress(this.props.coin, address, isZaddr) + .then((json) => { + let _items = []; + + for (let key in json) { + _items.push(`${key}: ${json[key]}`); + } + + Store.dispatch( + triggerToaster( + _items, + translate('TOASTR.COIN_NOTIFICATION'), + json && json.ismine ? 'info' : 'warning', + false, + 'toastr--validate-address' + ) + ); + }); + } + dumpPrivKey(address, isZaddr) { this.toggleAddressMenu(address); dumpPrivKey(this.props.coin, address, isZaddr) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 7b152bb..57f032a 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -30,6 +30,11 @@ export const AddressActionsNonBasiliskModeRender = function(address, type) { { translate('INDEX.COPY') + ' priv key (WIF)' } } + { this.props.mode !== 'spv' && +
  • this.validateCoinAddress(address, type !== 'public' ? true : null) }> + validate address +
  • + }
  • diff --git a/react/src/components/dashboard/sendCoin/sendCoin.js b/react/src/components/dashboard/sendCoin/sendCoin.js index 2d13901..7458d14 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.js @@ -211,11 +211,12 @@ class SendCoin extends React.Component { renderAddressByType(type) { let _items = []; + const _coinAddresses = this.props.ActiveCoin.addresses; - if (this.props.ActiveCoin.addresses && - this.props.ActiveCoin.addresses[type] && - this.props.ActiveCoin.addresses[type].length) { - this.props.ActiveCoin.addresses[type].map((address) => { + if (_coinAddresses && + _coinAddresses[type] && + _coinAddresses[type].length) { + _coinAddresses[type].map((address) => { if (address.amount > 0 && (type !== 'public' || (address.canspend && type === 'public'))) { _items.push( diff --git a/react/src/components/dashboard/sendCoin/sendCoin.render.js b/react/src/components/dashboard/sendCoin/sendCoin.render.js index de08eee..c4966e1 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.render.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.render.js @@ -275,14 +275,16 @@ export const SendRender = function() { { translate('SEND.SUCCESS_SM') } - - - { translate('INDEX.SEND_FROM') } - - - { this.props.ActiveCoin.mode === 'spv' ? this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub : this.state.sendFrom } - - + { this.state.sendFrom && + + + { translate('INDEX.SEND_FROM') } + + + { this.props.ActiveCoin.mode === 'spv' ? this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub : this.state.sendFrom } + + + } { translate('INDEX.SEND_TO') } diff --git a/react/src/components/dashboard/settings/settings.exportKeysPanel.js b/react/src/components/dashboard/settings/settings.exportKeysPanel.js index 21c88ed..35de2fb 100644 --- a/react/src/components/dashboard/settings/settings.exportKeysPanel.js +++ b/react/src/components/dashboard/settings/settings.exportKeysPanel.js @@ -43,7 +43,7 @@ class ExportKeysPanel extends React.Component { if (keys === 'error') { Store.dispatch( triggerToaster( - translate('SETTINGS.WRONG_PASSPHRASE'), + translate('SETTINGS.WRONG_PASSPHRASE') + ' or WIF key format', translate('TOASTR.WALLET_NOTIFICATION'), 'error' ) diff --git a/react/src/components/dashboard/walletsInfo/walletsInfo.render.js b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js index cce0057..4025c28 100644 --- a/react/src/components/dashboard/walletsInfo/walletsInfo.render.js +++ b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js @@ -28,7 +28,7 @@ const WalletsInfoRender = function() { - { translate('WALLETS_INFO.ADRESS_LOCAL') } + { translate('WALLETS_INFO.ADDRESS_LOCAL') } { _netPeers[i].addrlocal } diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js index ad4e50e..c46f8a0 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js @@ -2,6 +2,7 @@ import React from 'react'; import { translate } from '../../../translate/translate'; import { secondsToString } from '../../../util/time'; import Config from '../../../config'; +import { isKomodoCoin } from '../../../util/coinHelper'; const WalletsTxInfoRender = function(txInfo) { return ( @@ -190,6 +191,7 @@ const WalletsTxInfoRender = function(txInfo) {
    { this.state.txDetails && this.props.ActiveCoin.coin !== 'CHIPS' && + isKomodoCoin(this.props.ActiveCoin.coin) &&