Browse Source

Merge pull request #23 from SuperNETorg/v0.25

V0.25
v0.25
pbca26 7 years ago
committed by GitHub
parent
commit
53cca91854
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      react/package.json
  2. 38
      react/src/actions/actions/electrum.js
  3. 4
      react/src/components/addcoin/addcoinOptionsCrypto.js
  4. 7
      react/src/components/dashboard/notaryElectionsModal/notaryElectionsModal.scss
  5. 174
      react/src/components/dashboard/sendCoin/sendCoin.js
  6. 46
      react/src/components/dashboard/sendCoin/sendCoin.render.js
  7. 35
      react/src/components/dashboard/sendCoin/sendCoin.scss
  8. 1
      react/src/components/dashboard/walletsNav/walletsNav.render.js
  9. 3
      react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js
  10. 4
      react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js
  11. 46
      react/src/components/overrides.scss
  12. 1
      react/src/styles/index.scss
  13. 50
      react/src/util/explorerList.js

1
react/package.json

@ -38,6 +38,7 @@
"express": "^4.14.0", "express": "^4.14.0",
"file-loader": "^0.10.0", "file-loader": "^0.10.0",
"qrcode.react": "^0.7.1", "qrcode.react": "^0.7.1",
"rc-slider": "8.5.0",
"react": "^15.3.1", "react": "^15.3.1",
"react-dom": "^15.3.1", "react-dom": "^15.3.1",
"react-hot-loader": "^1.3.0", "react-hot-loader": "^1.3.0",

38
react/src/actions/actions/electrum.js

@ -11,6 +11,32 @@ import {
} from '../actionCreators'; } from '../actionCreators';
import Store from '../../store'; import Store from '../../store';
// src: atomicexplorer
export function shepherdGetRemoteBTCFees() {
return new Promise((resolve, reject) => {
fetch(`http://atomicexplorer.com/api/btc/fees`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.catch((error) => {
console.log(error);
Store.dispatch(
triggerToaster(
'shepherdGetRemoteBTCFees',
'Error',
'error'
)
);
})
.then(response => response.json())
.then(json => {
resolve(json);
});
});
}
export function shepherdElectrumSetServer(coin, address, port) { export function shepherdElectrumSetServer(coin, address, port) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/coins/server/set?address=${address}&port=${port}&coin=${coin}&token=${Config.token}`, { fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/coins/server/set?address=${address}&port=${port}&coin=${coin}&token=${Config.token}`, {
@ -198,11 +224,11 @@ export function shepherdElectrumCoinsState(json) {
} }
// value in sats // value in sats
export function shepherdElectrumSend(coin, value, sendToAddress, changeAddress) { export function shepherdElectrumSend(coin, value, sendToAddress, changeAddress, btcFee) {
value = Math.floor(value); value = Math.floor(value);
return dispatch => { return dispatch => {
return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}&gui=true&push=true&verify=true&token=${Config.token}`, { return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}${btcFee ? '&btcfee=' + btcFee : ''}&gui=true&push=true&verify=true&token=${Config.token}`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -225,11 +251,11 @@ export function shepherdElectrumSend(coin, value, sendToAddress, changeAddress)
} }
} }
export function shepherdElectrumSendPromise(coin, value, sendToAddress, changeAddress) { export function shepherdElectrumSendPromise(coin, value, sendToAddress, changeAddress, btcFee) {
value = Math.floor(value); value = Math.floor(value);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}&gui=true&push=true&verify=true&token=${Config.token}`, { return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}${btcFee ? '&btcfee=' + btcFee : ''}&gui=true&push=true&verify=true&token=${Config.token}`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -252,11 +278,11 @@ export function shepherdElectrumSendPromise(coin, value, sendToAddress, changeAd
}); });
} }
export function shepherdElectrumSendPreflight(coin, value, sendToAddress, changeAddress) { export function shepherdElectrumSendPreflight(coin, value, sendToAddress, changeAddress, btcFee) {
value = Math.floor(value); value = Math.floor(value);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}&gui=true&push=false&verify=true&token=${Config.token}`, { fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/electrum/createrawtx?coin=${coin}&address=${sendToAddress}&value=${value}&change=${changeAddress}${btcFee ? '&btcfee=' + btcFee : ''}&gui=true&push=false&verify=true&token=${Config.token}`, {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

4
react/src/components/addcoin/addcoinOptionsCrypto.js

@ -24,11 +24,11 @@ const addCoinOptionsCrypto = () => {
label: 'BitcoinCash (BCH)', label: 'BitcoinCash (BCH)',
icon: 'BCH', icon: 'BCH',
value: `BCH|spv`, value: `BCH|spv`,
},/* { }, {
label: 'Bitcoin (BTC)', label: 'Bitcoin (BTC)',
icon: 'BTC', icon: 'BTC',
value: `BTC|spv`, value: `BTC|spv`,
}, */{ }, {
label: 'Crown (CRW)', label: 'Crown (CRW)',
icon: 'CRW', icon: 'CRW',
value: `CRW|spv`, value: `CRW|spv`,

7
react/src/components/dashboard/notaryElectionsModal/notaryElectionsModal.scss

@ -167,4 +167,11 @@
display: block; display: block;
} }
} }
}
.page-login .notary-elections-modal {
input,
textarea {
color: #5f5d5d;
}
} }

174
react/src/components/dashboard/sendCoin/sendCoin.js

@ -10,6 +10,7 @@ import {
clearLastSendToResponseState, clearLastSendToResponseState,
shepherdElectrumSend, shepherdElectrumSend,
shepherdElectrumSendPreflight, shepherdElectrumSendPreflight,
shepherdGetRemoteBTCFees,
copyString, copyString,
} from '../../../actions/actionCreators'; } from '../../../actions/actionCreators';
import Store from '../../../store'; import Store from '../../../store';
@ -21,11 +22,21 @@ import {
} from './sendCoin.render'; } from './sendCoin.render';
import { isPositiveNumber } from '../../../util/number'; import { isPositiveNumber } from '../../../util/number';
import mainWindow from '../../../util/mainWindow'; import mainWindow from '../../../util/mainWindow';
import explorerList from '../../../util/explorerList';
import Slider, { Range } from 'rc-slider';
import ReactTooltip from 'react-tooltip';
// TODO: - add links to explorers // TODO: - add links to explorers
// - render z address trim // - render z address trim
// - handle click outside // - handle click outside
const _feeLookup = [
'fastestFee',
'halfHourFee',
'hourFee',
'advanced'
];
class SendCoin extends React.Component { class SendCoin extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -44,7 +55,14 @@ class SendCoin extends React.Component {
coin: null, coin: null,
spvVerificationWarning: false, spvVerificationWarning: false,
spvPreflightSendInProgress: false, spvPreflightSendInProgress: false,
btcFees: {},
btcFeesType: 'halfHourFee',
btcFeesAdvancedStep: 9,
btcFeesSize: 0,
btcFeesTimeBasedStep: 1,
btcPreflightRes: null,
}; };
this.defaultState = JSON.parse(JSON.stringify(this.state));
this.updateInput = this.updateInput.bind(this); this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this); this.handleSubmit = this.handleSubmit.bind(this);
this.openDropMenu = this.openDropMenu.bind(this); this.openDropMenu = this.openDropMenu.bind(this);
@ -58,13 +76,17 @@ class SendCoin extends React.Component {
this.isFullySynced = this.isFullySynced.bind(this); this.isFullySynced = this.isFullySynced.bind(this);
this.setSendAmountAll = this.setSendAmountAll.bind(this); this.setSendAmountAll = this.setSendAmountAll.bind(this);
this.setSendToSelf = this.setSendToSelf.bind(this); this.setSendToSelf = this.setSendToSelf.bind(this);
this.fetchBTCFees = this.fetchBTCFees.bind(this);
this.onSliderChange = this.onSliderChange.bind(this);
this.onSliderChangeTime = this.onSliderChangeTime.bind(this);
} }
setSendAmountAll() { setSendAmountAll() {
const _amount = this.state.amount; const _amount = this.state.amount;
const _amountSats = this.state.amount * 100000000; const _amountSats = this.state.amount * 100000000;
const _balanceSats = this.props.ActiveCoin.balance.balanceSats; const _balanceSats = this.props.ActiveCoin.balance.balanceSats;
const _fees = mainWindow.spvFees; let _fees = mainWindow.spvFees;
_fees.BTC = 0;
this.setState({ this.setState({
amount: Number((0.00000001 * (_balanceSats - _fees[this.props.ActiveCoin.coin])).toFixed(8)), amount: Number((0.00000001 * (_balanceSats - _fees[this.props.ActiveCoin.coin])).toFixed(8)),
@ -82,7 +104,7 @@ class SendCoin extends React.Component {
} }
openExplorerWindow(txid) { openExplorerWindow(txid) {
const url = `http://${this.props.ActiveCoin.coin}.explorer.supernet.org/tx/${txid}`; const url = explorerList[this.props.ActiveCoin.coin].split('/').length - 1 > 2 ? `${explorerList[this.props.ActiveCoin.coin]}${txid}` : `${explorerList[this.props.ActiveCoin.coin]}/tx/${txid}`;
const remote = window.require('electron').remote; const remote = window.require('electron').remote;
const BrowserWindow = remote.BrowserWindow; const BrowserWindow = remote.BrowserWindow;
@ -136,6 +158,11 @@ class SendCoin extends React.Component {
Store.dispatch(clearLastSendToResponseState()); Store.dispatch(clearLastSendToResponseState());
} }
this.checkZAddressCount(props); this.checkZAddressCount(props);
if (this.props.ActiveCoin.activeSection !== props.ActiveCoin.activeSection &&
this.props.ActiveCoin.activeSection !== 'send') {
this.fetchBTCFees();
}
} }
setRecieverFromScan(receiver) { setRecieverFromScan(receiver) {
@ -400,8 +427,29 @@ class SendCoin extends React.Component {
}); });
} }
fetchBTCFees() {
if (this.props.ActiveCoin.mode === 'spv' &&
this.props.ActiveCoin.coin === 'BTC') {
shepherdGetRemoteBTCFees()
.then((res) => {
if (res.msg === 'success') {
// TODO: check, approx fiat value
this.setState({
btcFees: res.result,
btcFeesSize: this.state.btcFeesType === 'advanced' ? res.result.electrum[this.state.btcFeesAdvancedStep] : res.result.recommended[_feeLookup[this.state.btcFeesTimeBasedStep]],
});
} else {
// TODO: fallback to local electrum
}
console.warn('btcfees', res);
});
}
}
changeSendCoinStep(step, back) { changeSendCoinStep(step, back) {
if (step === 0) { if (step === 0) {
this.fetchBTCFees();
if (back) { if (back) {
this.setState({ this.setState({
currentStep: 0, currentStep: 0,
@ -411,21 +459,7 @@ class SendCoin extends React.Component {
} else { } else {
Store.dispatch(clearLastSendToResponseState()); Store.dispatch(clearLastSendToResponseState());
this.setState({ this.setState(this.defaultState);
currentStep: 0,
addressType: null,
sendFrom: null,
sendFromAmount: 0,
sendTo: '',
sendToOA: null,
amount: 0,
fee: 0,
addressSelectorOpen: false,
renderAddressDropdown: true,
subtractFee: false,
spvVerificationWarning: false,
spvPreflightSendInProgress: false,
});
} }
} }
@ -444,7 +478,8 @@ class SendCoin extends React.Component {
this.props.ActiveCoin.coin, this.props.ActiveCoin.coin,
this.state.amount * 100000000, this.state.amount * 100000000,
this.state.sendTo, this.state.sendTo,
this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub,
this.props.ActiveCoin.coin === 'BTC' ? this.state.btcFeesSize : null
) )
.then((sendPreflight) => { .then((sendPreflight) => {
if (sendPreflight && if (sendPreflight &&
@ -452,6 +487,7 @@ class SendCoin extends React.Component {
this.setState(Object.assign({}, this.state, { this.setState(Object.assign({}, this.state, {
spvVerificationWarning: !sendPreflight.result.utxoVerified, spvVerificationWarning: !sendPreflight.result.utxoVerified,
spvPreflightSendInProgress: false, spvPreflightSendInProgress: false,
btcPreflightRes: this.props.ActiveCoin.coin === 'BTC' ? { fee: sendPreflight.result.fee, value: sendPreflight.result.value, change: sendPreflight.result.change } : null,
})); }));
} else { } else {
this.setState(Object.assign({}, this.state, { this.setState(Object.assign({}, this.state, {
@ -502,7 +538,8 @@ class SendCoin extends React.Component {
this.props.ActiveCoin.coin, this.props.ActiveCoin.coin,
this.state.amount * 100000000, this.state.amount * 100000000,
this.state.sendTo, this.state.sendTo,
this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub this.props.Dashboard.electrumCoins[this.props.ActiveCoin.coin].pub,
this.props.ActiveCoin.coin === 'BTC' ? this.state.btcFeesSize : null
) )
); );
} }
@ -517,7 +554,8 @@ class SendCoin extends React.Component {
const _amount = this.state.amount; const _amount = this.state.amount;
const _amountSats = this.state.amount * 100000000; const _amountSats = this.state.amount * 100000000;
const _balanceSats = this.props.ActiveCoin.balance.balanceSats; const _balanceSats = this.props.ActiveCoin.balance.balanceSats;
const _fees = mainWindow.spvFees; let _fees = mainWindow.spvFees;
_fees.BTC = 0;
if (Number(_amountSats) + _fees[this.props.ActiveCoin.coin] > _balanceSats) { if (Number(_amountSats) + _fees[this.props.ActiveCoin.coin] > _balanceSats) {
Store.dispatch( Store.dispatch(
@ -638,6 +676,102 @@ class SendCoin extends React.Component {
} }
} }
onSliderChange(value) {
console.warn(value);
console.warn(`btc fee /byte ${this.state.btcFees.electrum[value]}`);
this.setState({
btcFeesSize: this.state.btcFees.electrum[value],
btcFeesAdvancedStep: value,
});
}
onSliderChangeTime(value) {
console.warn(value);
console.warn(`btc fee /byte ${_feeLookup[value]}`);
this.setState({
btcFeesSize: this.state.btcFees.recommended[_feeLookup[value]],
btcFeesTimeBasedStep: value,
btcFeesType: _feeLookup[value] === 'advanced' ? 'advanced' : null,
});
}
renderBTCFees() {
if (this.props.ActiveCoin.mode === 'spv' &&
this.props.ActiveCoin.coin === 'BTC' &&
!this.state.btcFees.lastUpdated) {
return (<div className="col-lg-6 form-group form-material">Fetching BTC fees...</div>);
} else if (this.props.ActiveCoin.mode === 'spv' && this.props.ActiveCoin.coin === 'BTC' && this.state.btcFees.lastUpdated) {
const _min = 0;
const _max = this.state.btcFees.electrum.length - 1;
const _confTime = [
'within less than 30 min',
'within 30 min',
'within 60 min',
];
const _minTimeBased = 0;
const _maxTimeBased = 3;
/*let _marks = {};
for (let i = _min; i < _max; i++) {
_marks[i] = i + 1;
}*/
return (
<div className="col-lg-12 form-group form-material">
<div>
<div>
Fee
<span>
<i
className="icon fa-question-circle settings-help"
data-html={ true }
data-tip={ this.state.btcFeesType === 'advanced' ? 'Electrum based fee estimates may not be as accurate as bitcoinfees.earn.com.<br />It is advised to use fast/average/slow options if you want your transaction to be confirmed within 60 min time frame.' : 'Estimates are based on bitcoinfees.earn.com data.<br />Around 90% probability for a transaction to be confirmed within desired time frame.' }></i>
<ReactTooltip
effect="solid"
className="text-left" />
</span>
</div>
<div className="send-target-block">
{ this.state.btcFeesType !== 'advanced' &&
<span>Confirmation time <strong>{ _confTime[this.state.btcFeesTimeBasedStep] }</strong></span>
}
{ this.state.btcFeesType === 'advanced' &&
<span>Advanced selection</span>
}
</div>
<Slider
className="send-slider-time-based margin-bottom-70"
onChange={ this.onSliderChangeTime }
defaultValue={ this.state.btcFeesTimeBasedStep }
min={ _minTimeBased }
max={ _maxTimeBased }
dots={ true }
marks={{
0: 'fast',
1: 'average',
2: 'slow',
3: 'advanced'
}} />
{ this.state.btcFeesType === 'advanced' &&
<div>
<div className="send-target-block">Estimated to be included within the next <strong>{this.state.btcFeesAdvancedStep + 1} {(this.state.btcFeesAdvancedStep + 1) > 1 ? 'blocks' : 'block'}</strong></div>
<Slider
onChange={ this.onSliderChange }
defaultValue={ this.state.btcFeesAdvancedStep }
min={ _min }
max={ _max } />
</div>
}
{ this.state.btcFeesSize > 0 &&
<div className="margin-top-10">Fee per byte {this.state.btcFeesSize}, per KB {this.state.btcFeesSize * 1024}</div>
}
</div>
</div>
);
}
}
render() { render() {
if (this.props && if (this.props &&
this.props.ActiveCoin && this.props.ActiveCoin &&

46
react/src/components/dashboard/sendCoin/sendCoin.render.js

@ -1,7 +1,9 @@
import React from 'react'; import React from 'react';
import { translate } from '../../../translate/translate'; import { translate } from '../../../translate/translate';
import QRModal from '../qrModal/qrModal'; import QRModal from '../qrModal/qrModal';
import { isKomodoCoin } from '../../../util/coinHelper'; import { formatValue } from '../../../util/formatValue';
import explorerList from '../../../util/explorerList';
import ReactTooltip from 'react-tooltip';
export const AddressListRender = function() { export const AddressListRender = function() {
return ( return (
@ -117,6 +119,7 @@ export const _SendFormRender = function() {
</span> </span>
} }
</div> </div>
{ this.renderBTCFees() }
<div className="col-lg-6 form-group form-material hide"> <div className="col-lg-6 form-group form-material hide">
<label <label
className="control-label" className="control-label"
@ -169,7 +172,7 @@ export const SendRender = function() {
); );
} else { } else {
return ( return (
<div className="col-sm-12 padding-top-10"> <div className="col-sm-12 padding-top-10 coin-send-form">
<div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12"> <div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12">
<div className="steps row margin-top-10"> <div className="steps row margin-top-10">
<div className={ 'step col-md-4' + (this.state.currentStep === 0 ? ' current' : '') }> <div className={ 'step col-md-4' + (this.state.currentStep === 0 ? ' current' : '') }>
@ -241,6 +244,38 @@ export const SendRender = function() {
</div> </div>
</div> </div>
} }
{ this.state.btcPreflightRes &&
<div className="row padding-top-20">
<div className="col-xs-12">
<strong>Fee</strong>
</div>
<div className="col-lg-12 col-sm-12 col-xs-12">{ formatValue(this.state.btcPreflightRes.fee * 0.00000001) } ({ this.state.btcPreflightRes.fee } sats)</div>
</div>
}
{ this.state.btcPreflightRes &&
<div className="row padding-top-20">
{ this.state.btcPreflightRes.change === 0 &&
<div className="col-lg-12 col-sm-12 col-xs-12">
<strong>Adjusted amount</strong>
<span>
<i
className="icon fa-question-circle settings-help send-btc"
data-tip="Max. available amount to spend - transaction fee"></i>
<ReactTooltip
effect="solid"
className="text-left" />
</span>
&nbsp;{ formatValue((this.state.btcPreflightRes.value * 0.00000001) - (this.state.btcPreflightRes.fee * 0.00000001)) }
</div>
}
{ this.state.btcPreflightRes.change > 0 &&
<div className="col-lg-12 col-sm-12 col-xs-12">
<strong>Total (amount + transaction fee)</strong>&nbsp;
{ formatValue((this.state.btcPreflightRes.value * 0.00000001) + (this.state.btcPreflightRes.fee * 0.00000001)) }
</div>
}
</div>
}
{ this.state.spvPreflightSendInProgress && { this.state.spvPreflightSendInProgress &&
<div className="padding-top-20">{ translate('SEND.SPV_VERIFYING') }...</div> <div className="padding-top-20">{ translate('SEND.SPV_VERIFYING') }...</div>
} }
@ -338,7 +373,7 @@ export const SendRender = function() {
this.state.lastSendToResponse && this.state.lastSendToResponse &&
this.state.lastSendToResponse.txid) || this.state.lastSendToResponse.txid) ||
(this.props.ActiveCoin.mode === 'native' && this.state.lastSendToResponse && this.state.lastSendToResponse.length === 64)) && (this.props.ActiveCoin.mode === 'native' && this.state.lastSendToResponse && this.state.lastSendToResponse.length === 64)) &&
isKomodoCoin(this.props.ActiveCoin.coin) && explorerList[this.props.ActiveCoin.coin] &&
<div className="margin-top-10"> <div className="margin-top-10">
<button <button
type="button" type="button"
@ -364,7 +399,10 @@ export const SendRender = function() {
<strong className="text-capitalize">{ translate('API.ERROR_SM') }</strong> <strong className="text-capitalize">{ translate('API.ERROR_SM') }</strong>
</div> </div>
{ (this.state.lastSendToResponse.result.toLowerCase().indexOf('decode error') > -1) && { (this.state.lastSendToResponse.result.toLowerCase().indexOf('decode error') > -1) &&
<div>Your history contains shielded transactions(z).<br />Please move funds to another transparent address in order to use Lite mode.</div> <div>
Your history contains shielded transactions(z).<br />
Please move funds to another transparent address in order to use Lite mode.
</div>
} }
{ this.state.lastSendToResponse.result.toLowerCase().indexOf('decode error') === -1 && { this.state.lastSendToResponse.result.toLowerCase().indexOf('decode error') === -1 &&
<div>{ this.state.lastSendToResponse.result }</div> <div>{ this.state.lastSendToResponse.result }</div>

35
react/src/components/dashboard/sendCoin/sendCoin.scss

@ -13,4 +13,39 @@
right: 16px; right: 16px;
top: 20px; top: 20px;
padding: 0 11px; padding: 0 11px;
}
.extcoin-send-form {
.send-target-block {
margin-bottom: 14px;
margin-top: 10px;
}
.rc-slider {
left: 4px;
&.send-slider-time-based {
.rc-slider-mark {
margin-top: 3px;
.rc-slider-mark-text:first-child {
left: 8px !important;
}
.rc-slider-mark-text:last-child {
left: calc(100% - 20px) !important;
}
}
}
}
}
.coin-send-form {
overflow: hidden;
.settings-help {
&.send-btc {
margin: 0 7px 0 5px;
left: inherit;
}
}
} }

1
react/src/components/dashboard/walletsNav/walletsNav.render.js

@ -54,7 +54,6 @@ export const WalletsNavWithWalletRender = function() {
<i className="icon md-view-dashboard"></i> { translate('INDEX.TRANSACTIONS') } <i className="icon md-view-dashboard"></i> { translate('INDEX.TRANSACTIONS') }
</button> </button>
{ this.props.ActiveCoin && { this.props.ActiveCoin &&
this.props.ActiveCoin.coin !== 'BTC' &&
<button <button
type="button" type="button"
className="btn btn-primary waves-effect waves-light" className="btn btn-primary waves-effect waves-light"

3
react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js

@ -8,6 +8,7 @@ import {
} from '../../../actions/actionCreators'; } from '../../../actions/actionCreators';
import Store from '../../../store'; import Store from '../../../store';
import WalletsTxInfoRender from './walletsTxInfo.render'; import WalletsTxInfoRender from './walletsTxInfo.render';
import explorerList from '../../../util/explorerList';
class WalletsTxInfo extends React.Component { class WalletsTxInfo extends React.Component {
constructor() { constructor() {
@ -91,7 +92,7 @@ class WalletsTxInfo extends React.Component {
} }
openExplorerWindow(txid) { openExplorerWindow(txid) {
const url = `http://${this.props.ActiveCoin.coin}.explorer.supernet.org/tx/${txid}`; const url = explorerList[this.props.ActiveCoin.coin].split('/').length - 1 > 2 ? `${explorerList[this.props.ActiveCoin.coin]}${txid}` : `${explorerList[this.props.ActiveCoin.coin]}/tx/${txid}`;
const remote = window.require('electron').remote; const remote = window.require('electron').remote;
const BrowserWindow = remote.BrowserWindow; const BrowserWindow = remote.BrowserWindow;

4
react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js

@ -2,7 +2,7 @@ import React from 'react';
import { translate } from '../../../translate/translate'; import { translate } from '../../../translate/translate';
import { secondsToString } from '../../../util/time'; import { secondsToString } from '../../../util/time';
import Config from '../../../config'; import Config from '../../../config';
import { isKomodoCoin } from '../../../util/coinHelper'; import explorerList from '../../../util/explorerList';
const WalletsTxInfoRender = function(txInfo) { const WalletsTxInfoRender = function(txInfo) {
return ( return (
@ -191,7 +191,7 @@ const WalletsTxInfoRender = function(txInfo) {
<div className="modal-footer"> <div className="modal-footer">
{ this.state.txDetails && { this.state.txDetails &&
this.props.ActiveCoin.coin !== 'CHIPS' && this.props.ActiveCoin.coin !== 'CHIPS' &&
isKomodoCoin(this.props.ActiveCoin.coin) && explorerList[this.props.ActiveCoin.coin] &&
<button <button
type="button" type="button"
className="btn btn-sm white btn-dark waves-effect waves-light pull-left" className="btn btn-sm white btn-dark waves-effect waves-light pull-left"

46
react/src/components/overrides.scss

@ -332,4 +332,50 @@ select{
.cursor-default { .cursor-default {
cursor: default; cursor: default;
}
.rc-slider {
.rc-slider-handle {
position: absolute;
margin-left: -10px;
margin-top: -7px;
width: 20px;
height: 20px;
}
.rc-slider-mark {
top: 23px;
font-size: 14px;
}
.rc-slider-rail,
.rc-slider-track {
height: 6px;
}
.rc-slider-rail {
background-color: #dcdcdc;
}
.rc-slider-track {
background-color: #51c4f9;
}
.rc-slider-handle {
border-color: #51c4f9;
}
.rc-slider-dot {
bottom: -5px;
width: 12px;
height: 12px;
}
.rc-slider-dot-active {
border-color: #51c4f9 !important;
}
.rc-slider-dot {
border-color: #dcdcdc;
}
} }

1
react/src/styles/index.scss

@ -58,6 +58,7 @@
@import '../components/toaster/toaster.scss'; @import '../components/toaster/toaster.scss';
@import '~react-table/react-table.css'; @import '~react-table/react-table.css';
@import '~react-select/dist/react-select.css'; @import '~react-select/dist/react-select.css';
@import '~rc-slider/assets/index.css';
/* dex */ /* dex */
@import 'dex/main.scss'; @import 'dex/main.scss';

50
react/src/util/explorerList.js

@ -0,0 +1,50 @@
// TODO: add at least 2 explorers per coin
const explorerList = {
KMD: 'http://www.kmdexplorer.ru',
MSHARK: 'http://MSHARK.explorer.supernet.org',
REVS: 'http://revs.explorer.supernet.org',
SUPERNET: 'http://SUPERNET.explorer.supernet.org',
DEX: 'http://DEX.explorer.supernet.org',
PANGEA: 'http://PANGEA.explorer.supernet.org',
JUMBLR: 'http://JUMBLR.explorer.supernet.org',
BET: 'http://BET.explorer.supernet.org',
CRYPTO: 'http://CRYPTO.explorer.supernet.org',
HODL: 'http://HODL.explorer.supernet.org',
SHARK: 'http://SHARK.explorer.supernet.org',
BOTS: 'http://BOTS.explorer.supernet.org',
MGW: 'http://MGW.explorer.supernet.org',
WLC: 'http://WIRELESS.explorer.supernet.org',
CHIPS: 'http://CHIPS1.explorer.supernet.org',
COQUI: 'https://explorer.coqui.cash',
MNZ: 'https://www.mnzexplorer.com',
BTCH: 'http://www.btch.host',
BTC: 'https://blockchain.info',
HUSH: 'https://explorer.myhush.org',
PIZZA: 'http://pizza.komodochainz.info',
BEER: 'http://beer.komodochainz.info',
QTUM: 'https://explorer.qtum.org',
LTC: 'https://live.blockcypher.com/ltc',
DOGE: 'https://live.blockcypher.com/doge',
DASH: 'https://live.blockcypher.com/dash',
MONA: 'https://bchain.info/MONA',
VIA: 'https://explorer.viacoin.org',
VTC: 'http://explorer.vertcoin.info',
NMC: 'https://namecha.in',
DGB: 'https://digiexplorer.info',
CRW: 'http://ex.crownlab.eu',
BTG: 'https://btgexplorer.com',
BCH: 'https://bitcoincash.blockexplorer.com',
ZCL: 'http://explorer.zclmine.pro',
ZMY: 'https://myriadexplorer.com',
BTX: 'http://explorer.bitcore.cc',
BTCZ: 'https://explorer.bitcoinz.site',
HODLC: 'http://www.fuzzbawls.pw/explore/HOdlcoin/tx.php?tx=',
SIB: 'https://chain.sibcoin.net/en/tx/',
ZEC: 'https://explorer.zcha.in/transactions/',
BLK: 'https://explorer.coinpayments.net/transaction.php?chain=4&hash=',
ARG: 'https://prohashing.com/explorer/Argentum/',
FAIR: 'https://chain.fair.to/transaction?transaction=',
};
export default explorerList;
Loading…
Cancel
Save