From c017b0a7bb5d6e8524c77c3f08ab756bd50ee1a6 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 6 Jul 2017 10:02:20 -0700 Subject: [PATCH 01/58] unlock jumblr menu tab --- react/src/components/dashboard/navbar/navbar.render.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js index 1bba47d..625b468 100644 --- a/react/src/components/dashboard/navbar/navbar.render.js +++ b/react/src/components/dashboard/navbar/navbar.render.js @@ -55,7 +55,7 @@ const NavbarRender = function() { EasyDEX -
  • +
  • this.dashboardChangeSection('jumblr') }> Jumblr From 507bb0f186638cdafb7c170ade9c2624656b1330 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 27 Jul 2017 04:43:51 -0700 Subject: [PATCH 02/58] added settings/about modal to login ui --- react/change.log | 1 + react/src/actions/actionCreators.js | 8 + react/src/actions/storeType.js | 3 +- .../components/dashboard/settings/settings.js | 6 +- .../dashboard/settings/settings.render.js | 227 +++++++++--------- react/src/components/login/login.js | 24 +- react/src/components/login/login.render.js | 38 ++- react/src/components/login/login.scss | 26 ++ react/src/reducers/main.js | 8 +- 9 files changed, 222 insertions(+), 119 deletions(-) diff --git a/react/change.log b/react/change.log index 534043b..980c898 100644 --- a/react/change.log +++ b/react/change.log @@ -10,6 +10,7 @@ UI: - komodod crash report modal - values rounding (up to 6 decimals) - add coin multi ui reflow fix +- reset app setting to default v0.2.0.21a-beta -------------- diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index baf8d37..f070101 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -25,6 +25,7 @@ import { DASHBOARD_ACTIVE_COIN_CHANGE, ACTIVE_COIN_GET_ADDRESSES, DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY, + DISPLAY_LOGIN_SETTINGS_MODAL, DISPLAY_COIND_DOWN_MODAL, START_INTERVAL, STOP_INTERVAL @@ -358,4 +359,11 @@ export function toggleCoindDownModal(display) { type: DISPLAY_COIND_DOWN_MODAL, displayCoindDownModal: display, } +} + +export function toggleLoginSettingsModal(display) { + return { + type: DISPLAY_LOGIN_SETTINGS_MODAL, + displayLoginSettingsModal: display, + } } \ No newline at end of file diff --git a/react/src/actions/storeType.js b/react/src/actions/storeType.js index d00021b..23deb33 100644 --- a/react/src/actions/storeType.js +++ b/react/src/actions/storeType.js @@ -44,4 +44,5 @@ export const LOAD_APP_INFO = 'LOAD_APP_INFO'; export const LOG_GUI_HTTP = 'LOG_GUI_HTTP'; export const CLI = 'CLI'; export const LOGOUT = 'LOGOUT'; -export const DISPLAY_COIND_DOWN_MODAL = 'DISPLAY_COIND_DOWN_MODAL'; \ No newline at end of file +export const DISPLAY_COIND_DOWN_MODAL = 'DISPLAY_COIND_DOWN_MODAL'; +export const DISPLAY_LOGIN_SETTINGS_MODAL = 'DISPLAY_LOGIN_SETTINGS_MODAL'; \ No newline at end of file diff --git a/react/src/components/dashboard/settings/settings.js b/react/src/components/dashboard/settings/settings.js index c1031cf..3d5f74d 100644 --- a/react/src/components/dashboard/settings/settings.js +++ b/react/src/components/dashboard/settings/settings.js @@ -62,6 +62,7 @@ class Settings extends React.Component { updateProgressPatch: null, wifkeysPassphrase: '', trimPassphraseTimer: null, + disableWalletSpecificUI: null, }; this.exportWifKeys = this.exportWifKeys.bind(this); this.updateInput = this.updateInput.bind(this); @@ -82,7 +83,9 @@ class Settings extends React.Component { } componentDidMount() { - Store.dispatch(iguanaActiveHandle()); + if (!this.props.disableWalletSpecificUI) { + Store.dispatch(iguanaActiveHandle()); + } Store.dispatch(getAppConfig()); Store.dispatch(getAppInfo()); } @@ -95,6 +98,7 @@ class Settings extends React.Component { activeTab: this.state.activeTab, activeTabHeight: _height, tabElId: this.state.tabElId, + disableWalletSpecificUI: props.disableWalletSpecificUI, })); } } diff --git a/react/src/components/dashboard/settings/settings.render.js b/react/src/components/dashboard/settings/settings.render.js index 5988490..c6a0ddc 100644 --- a/react/src/components/dashboard/settings/settings.render.js +++ b/react/src/components/dashboard/settings/settings.render.js @@ -156,57 +156,59 @@ export const SettingsRender = function() {
    -
    this.openTab('WalletInfo', 0) } - className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> - + { !this.props.disableWalletSpecificUI &&
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    { translate('INDEX.KEY') }{ translate('INDEX.VALUE') }
    pubkey{ this.props.Main.activeHandle.pubkey }
    btcpubkey{ this.props.Main.activeHandle.btcpubkey }
    rmd160{ this.props.Main.activeHandle.rmd160 }
    NXT{ this.props.Main.activeHandle.NXT }
    notary{ this.props.Main.activeHandle.notary }
    status{ this.props.Main.activeHandle.status }
    + id="WalletInfo" + onClick={ () => this.openTab('WalletInfo', 0) } + className={ 'panel' + (this.state.nativeOnly ? ' hide' : '') }> + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    { translate('INDEX.KEY') }{ translate('INDEX.VALUE') }
    pubkey{ this.props.Main.activeHandle.pubkey }
    btcpubkey{ this.props.Main.activeHandle.btcpubkey }
    rmd160{ this.props.Main.activeHandle.rmd160 }
    NXT{ this.props.Main.activeHandle.NXT }
    notary{ this.props.Main.activeHandle.notary }
    status{ this.props.Main.activeHandle.status }
    +
    -
    - + } + { !this.props.disableWalletSpecificUI &&
    this.openTab('AddNodeforCoin', 1) } @@ -292,7 +294,8 @@ export const SettingsRender = function() {
    - + } + { !this.props.disableWalletSpecificUI &&
    this.openTab('DumpWallet', 2) } @@ -308,7 +311,8 @@ export const SettingsRender = function() {
    Wallet Backup section to be updated soon.
    - + } + { !this.props.disableWalletSpecificUI &&
    this.openTab('FiatCurrencySettings', 3) } @@ -324,7 +328,8 @@ export const SettingsRender = function() {
    Fiat currency settings section to be updated soon.
    - + } + { !this.props.disableWalletSpecificUI &&
    this.openTab('ExportKeys', 4) } @@ -401,7 +406,8 @@ export const SettingsRender = function() {
    - + } + { !this.props.disableWalletSpecificUI &&
    this.openTab('ImportKeys', 5) } @@ -450,6 +456,7 @@ export const SettingsRender = function() {
    + }
    { this.renderAppInfoTab() } -
    this.openTab('Cli', 9) } - className={ 'panel' + (!this.props.Main.coins.native.length ? ' hide' : '') }> - + { this.props.Main && this.props.Main.coins.native &&
    -
    -

    { translate('INDEX.CLI_SELECT_A_COIN') }

    -
    -
    -
    - - -
    -
    - - -
    -
    - -
    -
    -
    - { this.renderCliResponse() } + id="Cli" + onClick={ () => this.openTab('Cli', 9) } + className={ 'panel' + (!this.props.Main.coins.native.length ? ' hide' : '') }> + +
    +
    +

    { translate('INDEX.CLI_SELECT_A_COIN') }

    +
    + +
    + +
    -
    - +
    + + +
    +
    + +
    +
    +
    + { this.renderCliResponse() } +
    +
    + +
    -
    + } { this.renderAppUpdateTab() }
    diff --git a/react/src/components/login/login.js b/react/src/components/login/login.js index 9fd8bc4..a2b475b 100644 --- a/react/src/components/login/login.js +++ b/react/src/components/login/login.js @@ -8,7 +8,8 @@ import { toggleSyncOnlyModal, getSyncOnlyForks, createNewWallet, - triggerToaster + triggerToaster, + toggleLoginSettingsModal } from '../../actions/actionCreators'; import Config from '../../config'; import Store from '../../store'; @@ -39,6 +40,8 @@ class Login extends React.Component { isCustomSeedWeak: false, nativeOnly: Config.iguanaLessMode, trimPassphraseTimer: null, + displayLoginSettingsDropdown: false, + displayLoginSettingsDropdownSection: null, }; this.toggleActivateCoinForm = this.toggleActivateCoinForm.bind(this); this.updateRegisterConfirmPassPhraseInput = this.updateRegisterConfirmPassPhraseInput.bind(this); @@ -51,11 +54,21 @@ class Login extends React.Component { this.copyPassPhraseToClipboard = this.copyPassPhraseToClipboard.bind(this); this.execWalletCreate = this.execWalletCreate.bind(this); this.resizeLoginTextarea = this.resizeLoginTextarea.bind(this); + this.toggleLoginSettingsDropdown = this.toggleLoginSettingsDropdown.bind(this); } // the setInterval handler for 'activeCoins' _iguanaActiveCoins = null; + toggleLoginSettingsDropdownSection(sectionName) { + Store.dispatch(toggleLoginSettingsModal(true)); + + this.setState({ + displayLoginSettingsDropdown: false, + displayLoginSettingsDropdownSection: sectionName, + }); + } + isCustomWalletSeed() { return this.state.customWalletSeed; } @@ -95,6 +108,9 @@ class Login extends React.Component { ); Store.dispatch(toggleSyncOnlyModal(true)); + this.setState({ + displayLoginSettingsDropdown: false, + }); } componentDidMount() { @@ -117,6 +133,12 @@ class Login extends React.Component { })); } + toggleLoginSettingsDropdown() { + this.setState(Object.assign({}, this.state, { + displayLoginSettingsDropdown: !this.state.displayLoginSettingsDropdown, + })); + } + componentWillReceiveProps(props) { if (props && props.Main && diff --git a/react/src/components/login/login.render.js b/react/src/components/login/login.render.js index 50f7995..45f3016 100644 --- a/react/src/components/login/login.render.js +++ b/react/src/components/login/login.render.js @@ -1,9 +1,13 @@ import React from 'react'; import { translate } from '../../translate/translate'; +import LoginSettingsModal from '../dashboard/loginSettingsModal/loginSettingsModal'; const LoginRender = function () { return (
    + { this.renderSwallModal() }
    @@ -16,12 +20,34 @@ const LoginRender = function () { alt="SuperNET Iguana" />
    -
    - - { translate('LOGIN.DISPLAY_SYNC_ONLY') } - +
    diff --git a/react/src/components/login/login.scss b/react/src/components/login/login.scss index ed3e5c3..4b07173 100644 --- a/react/src/components/login/login.scss +++ b/react/src/components/login/login.scss @@ -126,4 +126,30 @@ input[type="password"] { .floating-label { font-size: 13px; } +} + +.login-settings-dropdown { + font-size: 16px; + + .dropdown-menu { + left: 42%; + top: inherit; + } +} + +.login-settings-dropdown-trigger { + cursor: pointer; +} + +.login-settings-modal { + .modal-body { + overflow-y: scroll; + color: #757575; + } + .panel-title { + color: #757575; + } + a { + color: #fb8c00; + } } \ No newline at end of file diff --git a/react/src/reducers/main.js b/react/src/reducers/main.js index f000ae6..0381ef1 100644 --- a/react/src/reducers/main.js +++ b/react/src/reducers/main.js @@ -1,12 +1,14 @@ import { GET_ACTIVE_COINS, LOGIN, - ACTIVE_HANDLE + ACTIVE_HANDLE, + DISPLAY_LOGIN_SETTINGS_MODAL } from '../actions/storeType'; export function Main(state = { isLoggedIn: false, activeCoins: [], + displayLoginSettingsModal: false, }, action) { switch (action.type) { case GET_ACTIVE_COINS: @@ -23,6 +25,10 @@ export function Main(state = { isLoggedIn: action.isLoggedIn, activeHandle: action.handle, }); + case DISPLAY_LOGIN_SETTINGS_MODAL: + return Object.assign({}, state, { + displayLoginSettingsModal: action.displayLoginSettingsModal, + }); default: return state; } From a9f08f50dac1f007b71adf53d1a8a2f26577a086 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 27 Jul 2017 06:16:09 -0700 Subject: [PATCH 03/58] basilisk refresh btn (wip) --- react/src/actions/actions/basiliskCache.js | 3 +- .../walletsBalance/walletsBalance.js | 28 +++++++++++++++++++ .../walletsBalance/walletsBalance.render.js | 3 ++ react/src/components/overrides.scss | 6 ++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/react/src/actions/actions/basiliskCache.js b/react/src/actions/actions/basiliskCache.js index 07a5713..00d4087 100644 --- a/react/src/actions/actions/basiliskCache.js +++ b/react/src/actions/actions/basiliskCache.js @@ -67,10 +67,11 @@ export function fetchNewCacheData(_payload) { _coin = `&coin=${_payload.coin}`, _calls = `&calls=${_payload.calls}`, _address = _payload.address ? (`&address=${_payload.address}`) : '', + _skip = _payload.skip ? (`&skip=${_payload.skip}`) : '', _iguanaInstancePort = Config.useBasiliskInstance ? `&port=${Config.iguanaCorePort + 1}` : ''; return dispatch => { - return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/${_route}${_userpass}${_pubkey}${_coin}${_calls}${_address}${_iguanaInstancePort}`, { + return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/${_route}${_userpass}${_pubkey}${_coin}${_calls}${_address}${_skip}${_iguanaInstancePort}`, { method: 'GET', headers: { 'Content-Type': 'application/json', diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.js b/react/src/components/dashboard/walletsBalance/walletsBalance.js index 1dab912..a3b7a31 100755 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.js @@ -1,12 +1,27 @@ import React from 'react'; import { translate } from '../../../translate/translate'; +import { fetchNewCacheData } from '../../../actions/actionCreators'; +import Store from '../../../store'; import WalletsBalanceRender from './walletsBalance.render'; class WalletsBalance extends React.Component { constructor(props) { super(props); + this.state = { + currentAddress: null, + }; this.isFullySynced = this.isFullySynced.bind(this); + this.refreshBalance = this.refreshBalance.bind(this); + } + + componentWillReceiveProps(props) { + if (!this.state.currentAddress && + this.props.ActiveCoin.activeAddress) { + this.setState(Object.assign({}, this.state, { + currentAddress: this.props.ActiveCoin.activeAddress, + })); + } } isFullySynced() { @@ -21,6 +36,19 @@ class WalletsBalance extends React.Component { } } + refreshBalance() { + if (this.props.ActiveCoin.mode === 'basilisk') { + Store.dispatch(fetchNewCacheData({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': this.props.ActiveCoin.coin, + 'calls': 'getbalance', + 'skip': true, + 'address': this.state.currentAddress, + })); + } + } + renderBalance(type) { let _balance = '0'; const _mode = this.props.ActiveCoin.mode; diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js index 5a97998..4664e40 100644 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js @@ -26,6 +26,9 @@ const WalletsBalanceRender = function() {
    +
    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index 55cd8a3..d23281c 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -641,4 +641,10 @@ select{ .backround-gray { background: #f3f4f5; +} + +.manual-balance-refresh { + position: absolute; + right: 4px; + top: 3px; } \ No newline at end of file From e58ad7960e299f47cc54120ca742a1dccd98bbe9 Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Thu, 27 Jul 2017 19:55:01 +0300 Subject: [PATCH 04/58] QR Code feature --- react/package.json | 2 + .../components/dashboard/qrModal/qrModal.js | 71 ++++++++++++++ .../dashboard/qrModal/qrModal.render.js | 97 +++++++++++++++++++ .../receiveCoin/receiveCoin.render.js | 10 +- .../components/dashboard/sendCoin/sendCoin.js | 9 +- .../dashboard/sendCoin/sendCoin.render.js | 10 +- react/src/translate/en.js | 5 +- 7 files changed, 200 insertions(+), 4 deletions(-) create mode 100755 react/src/components/dashboard/qrModal/qrModal.js create mode 100644 react/src/components/dashboard/qrModal/qrModal.render.js diff --git a/react/package.json b/react/package.json index 81b81d2..656d1fd 100644 --- a/react/package.json +++ b/react/package.json @@ -38,10 +38,12 @@ "bluebird": "^3.5.0", "express": "^4.14.0", "file-loader": "^0.10.0", + "qrcode.react": "^0.7.1", "rc-tree": "^1.4.6", "react": "^15.3.1", "react-dom": "^15.3.1", "react-hot-loader": "^1.3.0", + "react-qr-reader": "^1.1.3", "react-redux": "^5.0.3", "react-router": "^3.0.2", "react-router-redux": "^4.0.4", diff --git a/react/src/components/dashboard/qrModal/qrModal.js b/react/src/components/dashboard/qrModal/qrModal.js new file mode 100755 index 0000000..fcd8560 --- /dev/null +++ b/react/src/components/dashboard/qrModal/qrModal.js @@ -0,0 +1,71 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; + +import Store from '../../../store'; +import { translate } from '../../../translate/translate'; +import QrReader from 'react-qr-reader' +import { + QRModalRender, + QRModalReaderRender +} from './qrModal.render'; + +class QRModal extends React.Component { + constructor(props) { + super(props); + + this.state = { + modalIsOpen: false, + error: "" + }; + + this.openModal = this.openModal.bind(this); + this.closeModal = this.closeModal.bind(this); + + this.handleScan = this.handleScan.bind(this); + this.handleError = this.handleError.bind(this); + + document.body.addEventListener('click', this.closeModal); + + } + + handleScan(data){ + if(data!==null) { + if(this.props.mode==="scan") { + this.props.setRecieverFromScan(data) + } + this.closeModal(); + } + return data; + } + handleError(err){ + this.setState({error: err}); + } + openModal() { + this.setState({modalIsOpen: true}); + if(this.props.mode==="scan") { + ReactDOM.render(, document.getElementById('webcam')); + } + } + closeModal() { + this.setState({modalIsOpen: false}); + if(this.props.mode==="scan") { + ReactDOM.unmountComponentAtNode(document.getElementById('webcam')); + } + } + render() { + if(this.props.mode==="scan") { + return QRModalReaderRender.call(this); + } else { + return QRModalRender.call(this); + } + + + } +} + +export default QRModal; diff --git a/react/src/components/dashboard/qrModal/qrModal.render.js b/react/src/components/dashboard/qrModal/qrModal.render.js new file mode 100644 index 0000000..9dd3b12 --- /dev/null +++ b/react/src/components/dashboard/qrModal/qrModal.render.js @@ -0,0 +1,97 @@ +import React from 'react'; +import { translate } from '../../../translate/translate'; +import QRCode from 'qrcode.react'; + +export const QRModalRender = function () { + return ( + + + + + +
    +
    + ); +}; + + +export const QRModalReaderRender = function () { + return ( + + + +
    +
    + ); +}; + + diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index f5acf16..108fb88 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -1,5 +1,6 @@ import React from 'react'; import { translate } from '../../../translate/translate'; +import QRModal from '../qrModal/qrModal'; export const AddressActionsBasiliskModeRender = function(address) { return ( @@ -25,6 +26,9 @@ export const AddressActionsBasiliskModeRender = function(address) { onClick={ () => this._validateAddressBasilisk(address) }> + ); }; @@ -41,6 +45,9 @@ export const AddressActionsNonBasiliskModeRender = function(address, type) { onClick={ () => this._copyCoinAddress(address) }> { translate('INDEX.COPY') } + ); }; @@ -140,4 +147,5 @@ export const ReceiveCoinRender = function() {
    ); -}; \ No newline at end of file +}; + diff --git a/react/src/components/dashboard/sendCoin/sendCoin.js b/react/src/components/dashboard/sendCoin/sendCoin.js index 3d41a4b..850d1f2 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.js @@ -64,9 +64,17 @@ class SendCoin extends React.Component { this.toggleSendAPIType = this.toggleSendAPIType.bind(this); this._fetchNewUTXOData = this._fetchNewUTXOData.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); + this.setRecieverFromScan = this.setRecieverFromScan.bind(this); socket.on('messages', msg => this.updateSocketsData(msg)); } + setRecieverFromScan(receiver) { + this.setState({ + sendTo: receiver + }); + document.getElementById('edexcoinSendTo').focus() + } + componentWillMount() { document.addEventListener( 'click', @@ -745,7 +753,6 @@ class SendCoin extends React.Component { return null; } - render() { if (this.props.ActiveCoin && this.props.ActiveCoin.send && diff --git a/react/src/components/dashboard/sendCoin/sendCoin.render.js b/react/src/components/dashboard/sendCoin/sendCoin.render.js index a7fc0a5..c7a3f5b 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.render.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.render.js @@ -5,6 +5,8 @@ import { secondsToString } from '../../../util/time'; +import QRModal from '../qrModal/qrModal'; + export const UTXOCacheInfoRender = function(refreshCacheData, isReadyToUpdate, waitUntilCallIsFinished, timestamp) { return (
    @@ -137,7 +139,7 @@ export const OASendUIRender = function () { export const SendApiTypeSelectorRender = function () { return (
    -
    +
    +
    + +
    ); }; diff --git a/react/src/translate/en.js b/react/src/translate/en.js index 8a47b93..4d5937c 100644 --- a/react/src/translate/en.js +++ b/react/src/translate/en.js @@ -249,7 +249,10 @@ export const _lang = { 'INFO': 'Info', 'ENTER': 'Enter', 'ADDR_SM': 'address', - 'ACTIVATING': 'Activating' + 'ACTIVATING': 'Activating', + 'QRCODE': 'Show QR code', + 'SCAN_QR_CODE': 'Scan QR Code', + 'SCAN_QRCODE_WEBCAM': 'Scan QR Code with webcam' }, 'ATOMIC': { 'RAW_OUTPUT': 'Raw Output', From c6382c215305ebacfba013a900448e87ca3be0d9 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 28 Jul 2017 12:21:20 +0300 Subject: [PATCH 05/58] missing loginSettingsModal component --- .../loginSettingsModal/loginSettingsModal.js | 32 +++++++++++++++++ .../loginSettingsModal.render.js | 36 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100755 react/src/components/dashboard/loginSettingsModal/loginSettingsModal.js create mode 100644 react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js diff --git a/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.js b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.js new file mode 100755 index 0000000..cea9312 --- /dev/null +++ b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.js @@ -0,0 +1,32 @@ +import React from 'react'; +import { getCoinTitle } from '../../../util/coinHelper'; +import { translate } from '../../../translate/translate'; +import { toggleLoginSettingsModal } from '../../../actions/actionCreators'; +import Store from '../../../store'; + +import { LoginSettingsModalRender } from './loginSettingsModal.render'; + +class LoginSettingsModal extends React.Component { + constructor(props) { + super(props); + this.state = { + }; + this.closeLoginSettingsModal = this.closeLoginSettingsModal.bind(this); + } + + closeLoginSettingsModal() { + Store.dispatch(toggleLoginSettingsModal(false)); + } + + render() { + if (this.props && + this.props.Main && + this.props.Main.displayLoginSettingsModal) { + return LoginSettingsModalRender.call(this); + } else { + return null; + } + } +} + +export default LoginSettingsModal; \ No newline at end of file diff --git a/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js new file mode 100644 index 0000000..3a84e50 --- /dev/null +++ b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { translate } from '../../../translate/translate'; +import About from '../about/about'; +import Settings from '../settings/settings'; + +export const LoginSettingsModalRender = function() { + console.log(this.props); + + return ( +
    +
    +
    +
    +
    + { this.props.section === 'settings' && + + } + { this.props.section === 'about' && + + } +
    +
    + +
    +
    +
    +
    +
    +
    + ); +}; \ No newline at end of file From 16908a893ee42e2078c536d4b4e3133063a5ee81 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 28 Jul 2017 20:17:49 +0300 Subject: [PATCH 06/58] manual balance and tx history refresh --- .../loginSettingsModal.render.js | 2 -- .../walletsBalance/walletsBalance.js | 35 +++++++++++++------ .../walletsBalance/walletsBalance.render.js | 2 +- .../dashboard/walletsData/walletsData.js | 30 +++++++++++++++- .../walletsData/walletsData.render.js | 3 ++ react/src/components/overrides.scss | 3 +- 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js index 3a84e50..8a59705 100644 --- a/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js +++ b/react/src/components/dashboard/loginSettingsModal/loginSettingsModal.render.js @@ -4,8 +4,6 @@ import About from '../about/about'; import Settings from '../settings/settings'; export const LoginSettingsModalRender = function() { - console.log(this.props); - return (
    diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.js b/react/src/components/dashboard/walletsBalance/walletsBalance.js index a3b7a31..c0f79c5 100755 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.js @@ -1,6 +1,10 @@ import React from 'react'; import { translate } from '../../../translate/translate'; -import { fetchNewCacheData } from '../../../actions/actionCreators'; +import { + fetchNewCacheData, + getKMDBalanceTotal, + iguanaEdexBalance +} from '../../../actions/actionCreators'; import Store from '../../../store'; import WalletsBalanceRender from './walletsBalance.render'; @@ -37,15 +41,26 @@ class WalletsBalance extends React.Component { } refreshBalance() { - if (this.props.ActiveCoin.mode === 'basilisk') { - Store.dispatch(fetchNewCacheData({ - 'pubkey': this.props.Dashboard.activeHandle.pubkey, - 'allcoins': false, - 'coin': this.props.ActiveCoin.coin, - 'calls': 'getbalance', - 'skip': true, - 'address': this.state.currentAddress, - })); + const _mode = this.props.ActiveCoin.mode; + const _coin = this.props.ActiveCoin.coin; + + switch(_mode) { + case 'basilisk': + Store.dispatch(fetchNewCacheData({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': this.props.ActiveCoin.coin, + 'calls': 'getbalance', + 'skip': true, + 'address': this.state.currentAddress, + })); + break; + case 'native': + Store.dispatch(getKMDBalanceTotal(_coin)); + break; + case 'full': + Store.dispatch(iguanaEdexBalance(_coin)); + break; } } diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js index 4664e40..6ce2b32 100644 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js @@ -27,7 +27,7 @@ const WalletsBalanceRender = function() {
    diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 2dffcd5..bc3ed5e 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -17,7 +17,9 @@ import { getDexNotaries, deleteCacheFile, fetchNewCacheData, - fetchUtxoCache + fetchUtxoCache, + getNativeTxHistory, + getFullTransactionsList } from '../../../actions/actionCreators'; import Store from '../../../store'; import { @@ -61,6 +63,7 @@ class WalletsData extends React.Component { this.restartBasiliskInstance = this.restartBasiliskInstance.bind(this); this.basiliskRefreshActionOne = this.basiliskRefreshActionOne.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); + this.refreshTxHistory = this.refreshTxHistory.bind(this); socket.on('messages', msg => this.updateSocketsData(msg)); } @@ -137,6 +140,31 @@ class WalletsData extends React.Component { } } + refreshTxHistory() { + const _mode = this.props.ActiveCoin.mode; + const _coin = this.props.ActiveCoin.coin; + + switch(_mode) { + case 'basilisk': + Store.dispatch(fetchNewCacheData({ + 'pubkey': this.props.Dashboard.activeHandle.pubkey, + 'allcoins': false, + 'coin': _coin, + 'calls': 'listtransactions', + 'skip': true, + 'address': this.state.currentAddress, + })); + break; + case 'native': + console.log('refresh'); + Store.dispatch(getNativeTxHistory(_coin)); + break; + case 'full': + Store.dispatch(getFullTransactionsList(_coin)); + break; + } + } + removeAndFetchNewCache() { Store.dispatch(deleteCacheFile({ 'pubkey': this.props.Dashboard.activeHandle.pubkey, diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js index f7e6fbb..078e2b0 100644 --- a/react/src/components/dashboard/walletsData/walletsData.render.js +++ b/react/src/components/dashboard/walletsData/walletsData.render.js @@ -157,6 +157,9 @@ export const WalletsDataRender = function() {
    +
    Date: Fri, 28 Jul 2017 20:25:55 +0300 Subject: [PATCH 07/58] dont log store updates in prod mode --- react/change.log | 2 ++ react/src/components/dashboard/walletsData/walletsData.js | 1 - react/src/components/login/login.render.js | 2 +- react/src/store.js | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/react/change.log b/react/change.log index 980c898..c376a6b 100644 --- a/react/change.log +++ b/react/change.log @@ -11,6 +11,8 @@ UI: - values rounding (up to 6 decimals) - add coin multi ui reflow fix - reset app setting to default +- manual balance / transactions list refresh +- quick access dropdown on login to open settings / about / sync only modals v0.2.0.21a-beta -------------- diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index bc3ed5e..84dc35d 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -156,7 +156,6 @@ class WalletsData extends React.Component { })); break; case 'native': - console.log('refresh'); Store.dispatch(getNativeTxHistory(_coin)); break; case 'full': diff --git a/react/src/components/login/login.render.js b/react/src/components/login/login.render.js index 45f3016..21bf49a 100644 --- a/react/src/components/login/login.render.js +++ b/react/src/components/login/login.render.js @@ -26,7 +26,7 @@ const LoginRender = function () { className="login-settings-dropdown-trigger" onClick={ this.toggleLoginSettingsDropdown }>   - Settings + Quick access
    diff --git a/react/src/store.js b/react/src/store.js index acd567c..1047d99 100644 --- a/react/src/store.js +++ b/react/src/store.js @@ -3,6 +3,7 @@ import thunkMiddleware from 'redux-thunk'; import createLogger from 'redux-logger'; import { syncHistoryWithStore } from 'react-router-redux'; import { browserHistory } from 'react-router'; +import Config from './config'; import rootReducer from './reducers/index'; @@ -19,7 +20,7 @@ const defaultState = { /* eslint-disable no-underscore-dangle */ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; -const enhancers = composeEnhancers(applyMiddleware(thunkMiddleware, loggerMiddleware)); +const enhancers = Config.debug || Config.dev ? composeEnhancers(applyMiddleware(thunkMiddleware, loggerMiddleware)) : composeEnhancers(applyMiddleware(thunkMiddleware)); const store = createStore( rootReducer, defaultState, From 92bdfd96f1fc204fedbb729ada5ca1f5cc9fb38a Mon Sep 17 00:00:00 2001 From: Miikat Date: Fri, 28 Jul 2017 20:36:53 +0300 Subject: [PATCH 08/58] Code formatting, small UI fix & Mirror video --- .../components/dashboard/qrModal/qrModal.js | 53 ++++++-------- .../dashboard/qrModal/qrModal.render.js | 73 +++++++++---------- .../dashboard/sendCoin/sendCoin.render.js | 12 +-- 3 files changed, 64 insertions(+), 74 deletions(-) diff --git a/react/src/components/dashboard/qrModal/qrModal.js b/react/src/components/dashboard/qrModal/qrModal.js index fcd8560..069bac2 100755 --- a/react/src/components/dashboard/qrModal/qrModal.js +++ b/react/src/components/dashboard/qrModal/qrModal.js @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom'; - import Store from '../../../store'; import { translate } from '../../../translate/translate'; import QrReader from 'react-qr-reader' @@ -10,62 +9,58 @@ import { } from './qrModal.render'; class QRModal extends React.Component { - constructor(props) { + constructor(props) { super(props); - this.state = { modalIsOpen: false, - error: "" + error: '' }; - this.openModal = this.openModal.bind(this); this.closeModal = this.closeModal.bind(this); - this.handleScan = this.handleScan.bind(this); this.handleError = this.handleError.bind(this); - document.body.addEventListener('click', this.closeModal); - - } + } - handleScan(data){ - if(data!==null) { - if(this.props.mode==="scan") { + handleScan(data) { + if(data !== null) { + if(this.props.mode === 'scan') { this.props.setRecieverFromScan(data) - } + } this.closeModal(); } - return data; } - handleError(err){ + + handleError(err) { this.setState({error: err}); } + openModal() { this.setState({modalIsOpen: true}); - if(this.props.mode==="scan") { - ReactDOM.render(, document.getElementById('webcam')); + if(this.props.mode === 'scan') { + ReactDOM.render( + , document.getElementById('webcam')); } } + closeModal() { this.setState({modalIsOpen: false}); - if(this.props.mode==="scan") { + if(this.props.mode === 'scan') { ReactDOM.unmountComponentAtNode(document.getElementById('webcam')); } } + render() { - if(this.props.mode==="scan") { - return QRModalReaderRender.call(this); + if(this.props.mode === 'scan') { + return QRModalReaderRender.call(this); } else { - return QRModalRender.call(this); + return QRModalRender.call(this); } - - } } -export default QRModal; +export default QRModal; \ No newline at end of file diff --git a/react/src/components/dashboard/qrModal/qrModal.render.js b/react/src/components/dashboard/qrModal/qrModal.render.js index 9dd3b12..9f63a5e 100644 --- a/react/src/components/dashboard/qrModal/qrModal.render.js +++ b/react/src/components/dashboard/qrModal/qrModal.render.js @@ -3,10 +3,9 @@ import { translate } from '../../../translate/translate'; import QRCode from 'qrcode.react'; export const QRModalRender = function () { - return ( - - + @@ -31,67 +30,63 @@ export const QRModalRender = function () {

    { translate('INDEX.SCAN_QR_CODE') }

    -
    -
    - -
    +
    +
    + +
    -
    -
    - +
    +
    + ); }; - export const QRModalReaderRender = function () { - return ( - + return ( + -
  • - { this.renderAddressByType('public') } { this.renderAddressByType('private') } @@ -28,6 +27,8 @@ export const AddressListRender = function() { ); }; +// { this.renderAddressByType('public') } + export const OASendUIRender = function() { return (
    @@ -74,12 +75,14 @@ export const WalletsNativeSendRender = function() { className="extcoin-send-form" method="post" autoComplete="off"> -
    -
    - - { this.renderAddressList() } + { this.zAddressCount && +
    +
    + + { this.renderAddressList() } +
    -
    + } { this.renderOASendUI() }
    From ced18c4b3368f82158684c05ad73a4824d02a5ee Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 29 Jul 2017 20:58:57 +0300 Subject: [PATCH 13/58] walletsData add/remove sockets --- react/src/actions/actionCreators.js | 3 -- react/src/actions/actions/addressBalance.js | 34 ++++++++++--------- .../components/dashboard/qrModal/qrModal.js | 8 ++--- .../receiveCoin/receiveCoin.render.js | 13 +++---- .../dashboard/settings/settings.render.js | 2 +- .../dashboard/walletsData/walletsData.js | 21 ++++++++++-- react/src/translate/translate.js | 8 ++--- 7 files changed, 48 insertions(+), 41 deletions(-) diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index f785cd6..69d451c 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -322,7 +322,6 @@ export function setBasiliskMainAddress(json, coin, mode) { } export function getNativeTxHistoryState(json) { - console.log('getNativeTxHistoryState', json.result.length); if (json && json.error) { json = null; @@ -332,8 +331,6 @@ export function getNativeTxHistoryState(json) { json = 'no data'; } - console.log('getNativeTxHistoryState', json); - return { type: DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY, txhistory: json, diff --git a/react/src/actions/actions/addressBalance.js b/react/src/actions/actions/addressBalance.js index 5f16784..e0acd18 100644 --- a/react/src/actions/actions/addressBalance.js +++ b/react/src/actions/actions/addressBalance.js @@ -249,25 +249,27 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { for (let a = 0; a < result.length; a++) { newAddressArray[a] = []; - for (let b = 0; b < result[a].length; b++) { - let filteredArray; + if (result[a]) { + for (let b = 0; b < result[a].length; b++) { + let filteredArray; + + if (mode === 'basilisk') { + filteredArray = json.map(res => res.amount); + } else { + filteredArray = json.filter(res => res.address === result[a][b]).map(res => res.amount); + } - if (mode === 'basilisk') { - filteredArray = json.map(res => res.amount); - } else { - filteredArray = json.filter(res => res.address === result[a][b]).map(res => res.amount); - } + let sum = 0; + for (let i = 0; i < filteredArray.length; i++) { + sum += filteredArray[i]; + } - let sum = 0; - for (let i = 0; i < filteredArray.length; i++) { - sum += filteredArray[i]; + newAddressArray[a][b] = { + address: result[a][b], + amount: currentAddress === result[a][b] || mode === 'native' ? sum : 'N/A', + type: a === 0 ? 'public': 'private', + }; } - - newAddressArray[a][b] = { - address: result[a][b], - amount: currentAddress === result[a][b] || mode === 'native' ? sum : 'N/A', - type: a === 0 ? 'public': 'private', - }; } } diff --git a/react/src/components/dashboard/qrModal/qrModal.js b/react/src/components/dashboard/qrModal/qrModal.js index 0866cc9..eea82dd 100755 --- a/react/src/components/dashboard/qrModal/qrModal.js +++ b/react/src/components/dashboard/qrModal/qrModal.js @@ -19,14 +19,14 @@ class QRModal extends React.Component { this.closeModal = this.closeModal.bind(this); this.handleScan = this.handleScan.bind(this); this.handleError = this.handleError.bind(this); - document.body.addEventListener('click', this.closeModal); } handleScan(data) { if (data !== null) { if (this.props.mode === 'scan') { - this.props.setRecieverFromScan(data) + this.props.setRecieverFromScan(data); } + this.closeModal(); } } @@ -60,10 +60,6 @@ class QRModal extends React.Component { this.setState({ modalIsOpen: false, }); - - if (this.props.mode === 'scan') { - ReactDOM.unmountComponentAtNode(document.getElementById('webcam')); - } } render() { diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 108fb88..0894f8d 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -26,9 +26,7 @@ export const AddressActionsBasiliskModeRender = function(address) { onClick={ () => this._validateAddressBasilisk(address) }> - + ); }; @@ -45,9 +43,7 @@ export const AddressActionsNonBasiliskModeRender = function(address, type) { onClick={ () => this._copyCoinAddress(address) }> { translate('INDEX.COPY') } - + ); }; @@ -76,8 +72,9 @@ export const ReceiveCoinRender = function() {
    {this.isNativeMode() &&
    -
    +
    { translate('INDEX.GET_NEW_ADDRESS') } diff --git a/react/src/components/dashboard/settings/settings.render.js b/react/src/components/dashboard/settings/settings.render.js index ebf4d97..aa17e53 100644 --- a/react/src/components/dashboard/settings/settings.render.js +++ b/react/src/components/dashboard/settings/settings.render.js @@ -593,7 +593,7 @@ export const SettingsRender = function() { diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 84dc35d..74fe8f3 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -64,7 +64,6 @@ class WalletsData extends React.Component { this.basiliskRefreshActionOne = this.basiliskRefreshActionOne.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); this.refreshTxHistory = this.refreshTxHistory.bind(this); - socket.on('messages', msg => this.updateSocketsData(msg)); } componentWillMount() { @@ -73,6 +72,14 @@ class WalletsData extends React.Component { this.handleClickOutside, false ); + + setTimeout(() => { + if (this.props.ActiveCoin.mode === 'basilisk') { + socket.on('messages', msg => this.updateSocketsData(msg)); + } else { + socket.removeAllListeners('messages'); + } + }, 100); } componentWillUnmount() { @@ -81,6 +88,8 @@ class WalletsData extends React.Component { this.handleClickOutside, false ); + + socket.removeAllListeners('messages'); } handleClickOutside(e) { @@ -576,8 +585,14 @@ class WalletsData extends React.Component { if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.coin && - !this.props.ActiveCoin.send && - !this.props.ActiveCoin.receive) { + ( + this.props.ActiveCoin.mode !== 'native' && + !this.props.ActiveCoin.send && + !this.props.ActiveCoin.receive + ) || ( + this.props.ActiveCoin.mode === 'native' && + this.props.ActiveCoin.nativeActiveSection === 'default' + )) { return WalletsDataRender.call(this); } else { return null; diff --git a/react/src/translate/translate.js b/react/src/translate/translate.js index 060f05d..631141b 100644 --- a/react/src/translate/translate.js +++ b/react/src/translate/translate.js @@ -13,13 +13,13 @@ export function translate(langID) { _lang[defaultLang][langIDComponents[0]][langIDComponents[1]]) { return _lang[defaultLang][langIDComponents[0]][langIDComponents[1]]; } else { - console.warn('Missing translation in js/' + defaultLang.toLowerCase() + '.js ' + langID); - return '--> ' + langID + ' <--'; + console.warn(`Missing translation ${langID} in js/${defaultLang.toLowerCase()}.js`); + return `--> ${langID} <--`; } } else { if (langID.length) { - console.warn('Missing translation in js/' + defaultLang.toLowerCase() + '.js ' + langID); - return '--> ' + langID + ' <--'; + console.warn(`Missing translation ${langID} in js/${defaultLang.toLowerCase()}.js`); + return `--> ${langID} <--`; } } } \ No newline at end of file From e92185997f9a9400e2c3f5032a452bf9a4396cc0 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 29 Jul 2017 23:47:49 +0300 Subject: [PATCH 14/58] equal balance boxes height --- .../walletsBalance/walletsBalance.render.js | 6 ++--- .../walletsNativeSend/walletsNativeSend.js | 21 ++++++++++++------ .../walletsNativeSend.render.js | 8 +++---- react/src/components/overrides.scss | 22 +++++++++++++++++++ 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js index 6ce2b32..e00db48 100644 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js @@ -5,8 +5,8 @@ import Config from '../../../config'; const WalletsBalanceRender = function() { return ( -
    -
    +
    +

    { translate('INDEX.ACTIVATING_WALLET_RT') }

    @@ -23,7 +23,7 @@ const WalletsBalanceRender = function() {
    -
    +
    - { this.zAddressCount && + { this.state.renderAddressDropdown &&
    @@ -104,7 +104,7 @@ export const WalletsNativeSendRender = function() {
    - { translate('INDEX.TOTAL') }: - { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) } + { translate('INDEX.TOTAL') }:  + { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  { this.props.ActiveCoin.coin }
    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index 5bee66c..c3af91e 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -648,4 +648,26 @@ select{ position: absolute; right: 4px; top: 3px; +} + +@media only screen and (min-width : 1201px) { + .wallet-widgets { + .flex { + display: flex; + flex-wrap: wrap; + } + > div { + display: flex; + + .widget, + .widget-content { + height: 100%; + + > div, + .clearfix { + height: 100%; + } + } + } + } } \ No newline at end of file From 6b3950e80be86ccd600e8deed18007b5c1c15198 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 29 Jul 2017 23:49:00 +0300 Subject: [PATCH 15/58] disabled fee, total, dropdown (t-tx) in native send --- .../walletsNativeSend/walletsNativeSend.js | 2 +- .../walletsNativeSend.render.js | 82 ++++++++++--------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js index 310a9b1..fe2cec2 100644 --- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js +++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js @@ -25,7 +25,7 @@ class WalletsNativeSend extends React.Component { sendTo: '', sendToOA: null, amount: 0, - fee: 0.0001, + fee: 0, addressSelectorOpen: false, renderAddressDropdown: true, }; diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js index 986b309..3d2f986 100644 --- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js +++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js @@ -100,7 +100,7 @@ export const WalletsNativeSendRender = function() { autoComplete="off" required />
    -
    +
    -
    +
    -
    +
    { translate('INDEX.TOTAL') }:  { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  @@ -143,7 +143,7 @@ export const WalletsNativeSendRender = function() { type="button" className="btn btn-primary waves-effect waves-light pull-right" onClick={ this.handleSubmit } - disabled={ !this.state.sendFrom || !this.state.sendTo || !this.state.amount }> + disabled={ (!this.state.sendFrom && this.state.renderAddressDropdown) || !this.state.sendTo || !this.state.amount }> { translate('INDEX.SEND') } { this.state.amount } { this.props.ActiveCoin.coin }
    @@ -153,48 +153,50 @@ export const WalletsNativeSendRender = function() {
    -
    -
    -
    -
    -
    -
    -
    -

    - { translate('INDEX.OPERATIONS_STATUSES') } -

    -
    -
    - - - - - - - - - - - { this.renderOPIDList() } - - - - - - - - - -
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    + { this.state.renderAddressDropdown && +
    +
    +
    +
    +
    +
    +
    +

    + { translate('INDEX.OPERATIONS_STATUSES') } +

    +
    +
    + + + + + + + + + + + { this.renderOPIDList() } + + + + + + + + + +
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    +
    -
    + }
    ); }; \ No newline at end of file From 058bafa29350a217deb104935c2b94c4aff9f7f9 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 29 Jul 2017 23:49:31 +0300 Subject: [PATCH 16/58] switched date sorting to conf --- react/src/actions/actions/nativeSend.js | 11 ++++++----- .../components/dashboard/walletsData/walletsData.js | 4 +++- .../dashboard/walletsData/walletsData.render.js | 8 ++++---- react/src/util/sort.js | 8 ++++---- react/src/util/time.js | 2 +- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index 8fea38e..cde0cfe 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -16,8 +16,9 @@ export function sendNativeTx(coin, _payload) { let payload; let _apiMethod; - if (_payload.addressType === 'public' && // transparent - _payload.sendTo.length !== 95) { + // iguana core + if ((_payload.addressType === 'public' && // transparent + _payload.sendTo.length !== 95) || !_payload.sendFrom) { _apiMethod = 'sendtoaddress'; ajaxDataToHex = `["${_payload.sendTo}", ${Number(_payload.amount) - Number(_payload.fee)}]`; } else { // private @@ -61,13 +62,13 @@ export function sendNativeTx(coin, _payload) { body: JSON.stringify(payload), }; - if (Config.cli.default) { + if (Config.cli.default) { // rpc payload = { mode: null, chain: coin, cmd: payload.function, params: - _payload.addressType === 'public' && _payload.sendTo.length !== 95 ? + (_payload.addressType === 'public' && _payload.sendTo.length !== 95) || !_payload.sendFrom ? [ _payload.sendTo, _payload.amount @@ -123,7 +124,7 @@ export function sendNativeTx(coin, _payload) { if (json.indexOf('"code":') > -1) { const _message = json.substring( - `${json.indexOf('"message":"')}11`, + `${json.indexOf('"message":"')}11`, json.indexOf('"},"id":"jl777"') ); diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 74fe8f3..52f2bc0 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -485,7 +485,9 @@ class WalletsData extends React.Component { _amount = _cache && _cache[_coin] && _cache[_coin][address] && _cache[_coin][address].getbalance.data && _cache[_coin][address].getbalance.data.balance ? _cache[_coin][address].getbalance.data.balance : 'N/A'; } - _amount = formatValue('round', _amount, -6); + if (_amount !== 'N/A') { + _amount = formatValue('round', _amount, -6); + } items.push(
  • diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js index 078e2b0..13d77f3 100644 --- a/react/src/components/dashboard/walletsData/walletsData.render.js +++ b/react/src/components/dashboard/walletsData/walletsData.render.js @@ -177,19 +177,19 @@ export const WalletsDataRender = function() {
      -
    • +
    • { translate('INDEX.GET_NOTARY_NODES_LIST') }
    • -
    • +
    • { translate('INDEX.REFRESH_BASILISK_CONNECTIONS') }
    • - { translate('INDEX.FETCH_WALLET_DATA') } + { translate('INDEX.FETCH_WALLET_DATA') }  ({ translate('INDEX.ACTIVE_ADDRESS') })
    • @@ -209,7 +209,7 @@ export const WalletsDataRender = function() { Restart Basilisk Instance (unsafe!) -
    • +
    • { translate('INDEX.VIEW_CACHE_DATA') } diff --git a/react/src/util/sort.js b/react/src/util/sort.js index 3ae1063..5904c6b 100644 --- a/react/src/util/sort.js +++ b/react/src/util/sort.js @@ -1,10 +1,10 @@ export function sortByDate(data) { return data.sort(function(a, b) { - if (a.timestamp && - b.timestamp) { - return b.timestamp - a.timestamp; + if (a.confirmations && + b.confirmations) { + return a.confirmations - b.confirmations; } else { - return b.blocktime - a.blocktime; + return a.confirmations - b.confirmations; } }); } \ No newline at end of file diff --git a/react/src/util/time.js b/react/src/util/time.js index 1e65f2b..a768ffe 100644 --- a/react/src/util/time.js +++ b/react/src/util/time.js @@ -18,7 +18,7 @@ export function secondsToString(seconds, skipMultiply, showSeconds) { month = months[a.getMonth()], date = a.getDate(), hour = a.getHours() < 10 ? `0${a.getHours()}` : a.getHours(), - min = a.getMinutes() < 10 ? `0 ${a.getMinutes()}` : a.getMinutes(), + min = a.getMinutes() < 10 ? `0${a.getMinutes()}` : a.getMinutes(), sec = a.getSeconds(), time = `${date} ${month} ${year} ${hour}:${min}${(showSeconds ? ':' + sec : '')}`; From 0add574d631c8fa36ce093f575a9c2178a5af0d2 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sun, 30 Jul 2017 13:25:54 +0300 Subject: [PATCH 17/58] basilisk send res render bug fix --- react/src/components/dashboard/sendCoin/sendCoin.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/react/src/components/dashboard/sendCoin/sendCoin.js b/react/src/components/dashboard/sendCoin/sendCoin.js index 39566aa..506881c 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.js @@ -697,6 +697,8 @@ class SendCoin extends React.Component { ); } } else if (key === 'sendrawtransaction') { + const _lastSendToResponse = this.props.ActiveCoin.lastSendToResponse; + if (_lastSendToResponse[key] === 'success') { return ( true @@ -707,6 +709,8 @@ class SendCoin extends React.Component { ); } } else if (key === 'txid' || key === 'sent') { + const _lastSendToResponse = this.props.ActiveCoin.lastSendToResponse; + return ( { _lastSendToResponse[key] } ); From f945c5e5e577e12323fe06a3c6dc3b87e07883b8 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sun, 30 Jul 2017 16:57:10 +0300 Subject: [PATCH 18/58] moved copy text field to walletMain comp --- react/src/components/main/walletMain.js | 1 + react/www/index.html | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/react/src/components/main/walletMain.js b/react/src/components/main/walletMain.js index 6c291ca..65e0e5c 100644 --- a/react/src/components/main/walletMain.js +++ b/react/src/components/main/walletMain.js @@ -10,6 +10,7 @@ class WalletMain extends React.Component { render() { return (
      + diff --git a/react/www/index.html b/react/www/index.html index d8d2d3a..8b1eb3a 100644 --- a/react/www/index.html +++ b/react/www/index.html @@ -1,21 +1,20 @@ - - - - - - Agama (v0.2.0.21a-beta) - - - - - - + + + + + + Agama (v0.2.0.21a-beta) + + + + + + -
      From 6749b830871f52d9ea8b495ef4dfd69f1c91acab Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sun, 30 Jul 2017 17:06:57 +0300 Subject: [PATCH 19/58] set app title from main comp --- react/src/components/main/main.js | 10 ++++++++++ react/www/index.html | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/react/src/components/main/main.js b/react/src/components/main/main.js index 9f18b85..e8350c0 100644 --- a/react/src/components/main/main.js +++ b/react/src/components/main/main.js @@ -23,6 +23,16 @@ class Main extends React.Component { } componentDidMount() { + let appVersion; + + try { + appVersion = window.require('electron').remote.getCurrentWindow().appBasicInfo; + } catch (e) {} + + if (appVersion) { + document.title = `${appVersion.name} (v${appVersion.version})`; + } + Store.dispatch(iguanaActiveHandle()); const _iguanaActiveHandle = setInterval(function() { Store.dispatch(iguanaActiveHandle()); diff --git a/react/www/index.html b/react/www/index.html index 8b1eb3a..3b7aa4c 100644 --- a/react/www/index.html +++ b/react/www/index.html @@ -6,7 +6,7 @@ - Agama (v0.2.0.21a-beta) + Agama From 0485951b522fd9302d2a37408257b6eaf55ec60c Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sun, 30 Jul 2017 18:50:53 +0300 Subject: [PATCH 20/58] settings comp sockets mount/unmount --- react/src/components/dashboard/settings/settings.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/react/src/components/dashboard/settings/settings.js b/react/src/components/dashboard/settings/settings.js index ed3baa2..bb31959 100644 --- a/react/src/components/dashboard/settings/settings.js +++ b/react/src/components/dashboard/settings/settings.js @@ -79,9 +79,16 @@ class Settings extends React.Component { this.toggleSeedInputVisibility = this.toggleSeedInputVisibility.bind(this); this._checkForUpdateUIPromise = this._checkForUpdateUIPromise.bind(this); this._updateUIPromise = this._updateUIPromise.bind(this); + } + + componentWillMount() { socket.on('patch', msg => this.updateSocketsData(msg)); } + componentWillUnmount() { + socket.removeAllListeners('patch', msg => this.updateSocketsData(msg)); + } + componentDidMount() { if (!this.props.disableWalletSpecificUI) { Store.dispatch(iguanaActiveHandle()); From 311552cbb9d92768679f80a8d1782bf832bd0e1f Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sun, 30 Jul 2017 18:51:34 +0300 Subject: [PATCH 21/58] basilisk send form reset bug fix --- .../components/dashboard/sendCoin/sendCoin.js | 2 +- .../dashboard/sendCoin/sendCoin.render.js | 106 +++++++++--------- .../dashboard/walletsData/walletsData.js | 48 ++++---- react/src/components/main/main.js | 2 +- react/src/components/overrides.scss | 8 ++ react/src/util/time.js | 6 +- 6 files changed, 94 insertions(+), 78 deletions(-) diff --git a/react/src/components/dashboard/sendCoin/sendCoin.js b/react/src/components/dashboard/sendCoin/sendCoin.js index 506881c..14a43f4 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.js @@ -395,7 +395,7 @@ class SendCoin extends React.Component { amount: 0, fee: 0.0001, sendSig: false, - sendApiType: false, + sendApiType: true, addressSelectorOpen: false, currentStackLength: 0, totalStackLength: 0, diff --git a/react/src/components/dashboard/sendCoin/sendCoin.render.js b/react/src/components/dashboard/sendCoin/sendCoin.render.js index 3745132..86b9da5 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.render.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.render.js @@ -8,6 +8,8 @@ import { import QRModal from '../qrModal/qrModal'; export const UTXOCacheInfoRender = function(refreshCacheData, isReadyToUpdate, waitUntilCallIsFinished, timestamp) { + const _progress = 100 - this.state.currentStackLength * 100 / this.state.totalStackLength; + return (

      @@ -25,7 +27,7 @@ export const UTXOCacheInfoRender = function(refreshCacheData, isReadyToUpdate, w
      + style={{ width: `${_progress}%` }}> { translate('SEND.PROCESSING_REQ') }: { this.state.currentStackLength } / { this.state.totalStackLength }
      @@ -59,50 +61,54 @@ export const SendCoinResponseRender = function() { return items; } else { return ( -
      -
      - { translate('SEND.PROCESSING_TRANSACTION') }...
      - { translate('SEND.NOTE_IT_WILL_TAKE') }. -
      -
      -
      -
      -
      + + +
      +
      + { translate('SEND.PROCESSING_TRANSACTION') }...
      + { translate('SEND.NOTE_IT_WILL_TAKE') }.
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      -
      -
      + + ); } } @@ -144,7 +150,8 @@ export const SendApiTypeSelectorRender = function() {
      @@ -247,9 +254,8 @@ export const SendCoinRender = function() { className="form-control" id="edexcoinAmount" name="amount" - placeholder="0.000" + placeholder="0.001" autoComplete="off" - defaultValue={ this.state.amount } value={ this.state.amount } onChange={ this.updateInput } />
      @@ -264,16 +270,15 @@ export const SendCoinRender = function() { className="form-control" id="edexcoinFee" name="fee" - defaultValue={ this.state.fee } value={ this.state.fee } - placeholder="0.000" + placeholder="0.001" autoComplete="off" onChange={ this.updateInput } />
      { translate('INDEX.TOTAL') }  - ({ translate('INDEX.AMOUNT_SM') } - txfee): + ({ translate('INDEX.AMOUNT_SM') } - fee):   { Number(this.state.amount) - Number(this.state.fee) } { this.props.ActiveCoin.coin }
      @@ -282,7 +287,8 @@ export const SendCoinRender = function() {
      - { this.stateisCameraFeatureDetected && + { this.state.isCameraFeatureDetected &&
        - { translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: - { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' } + { translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: + { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' }
      + { this.props.ActiveCoin.mode === 'native' && + + }
      -
      +
      { this.state.error }
      diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index e440235..a3214fb 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -124,12 +124,14 @@ class ReceiveCoin extends React.Component { if (this.isBasiliskMode() && this.hasNoAmount(address)) { address.amount = _cache && _cache[_coin][address.address] && + _cache[_coin][address.address].getbalance && _cache[_coin][address.address].getbalance.data && _cache[_coin][address.address].getbalance.data.balance ? _cache[_coin][address.address].getbalance.data.balance : 'N/A'; } if (this.isBasiliskMode() && this.hasNoInterest(address)) { address.interest = _cache && _cache[_coin][address.address] && + _cache[_coin][address.address].getbalance && _cache[_coin][address.address].getbalance.data && _cache[_coin][address.address].getbalance.data.interest ? _cache[_coin][address.address].getbalance.data.interest : 'N/A'; } diff --git a/react/src/components/dashboard/sendCoin/sendCoin.js b/react/src/components/dashboard/sendCoin/sendCoin.js index 14a43f4..bf1fe94 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.js @@ -55,7 +55,6 @@ class SendCoin extends React.Component { currentStackLength: 0, totalStackLength: 0, utxoMethodInProgress: false, - isCameraFeatureDetected: false, }; this.updateInput = this.updateInput.bind(this); this.handleBasiliskSend = this.handleBasiliskSend.bind(this); @@ -66,27 +65,9 @@ class SendCoin extends React.Component { this._fetchNewUTXOData = this._fetchNewUTXOData.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); this.setRecieverFromScan = this.setRecieverFromScan.bind(this); - this.detectCamera = this.detectCamera.bind(this); socket.on('messages', msg => this.updateSocketsData(msg)); } - // test device camera capabilities - detectCamera() { - const _getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; - - _getUserMedia( - { 'video': true }, - function() { - this.setState({ - isCameraFeatureDetected: true, - }); - }, - function() { - console.warn('this device doesn\'t have camera!'); - } - ); - } - setRecieverFromScan(receiver) { this.setState({ sendTo: receiver @@ -101,8 +82,6 @@ class SendCoin extends React.Component { this.handleClickOutside, false ); - - this.detectCamera(); } componentWillUnmount() { diff --git a/react/src/components/dashboard/sendCoin/sendCoin.render.js b/react/src/components/dashboard/sendCoin/sendCoin.render.js index b9749b4..43672d8 100644 --- a/react/src/components/dashboard/sendCoin/sendCoin.render.js +++ b/react/src/components/dashboard/sendCoin/sendCoin.render.js @@ -163,13 +163,11 @@ export const SendApiTypeSelectorRender = function() {
      - { this.state.isCameraFeatureDetected && -
      - -
      - } +
      + +
      ); }; diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index ddb32e5..e16a91e 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.render.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js @@ -41,7 +41,7 @@ export const WalletsNavWithWalletRender = function() { { this.props.ActiveCoin.mode === 'native' && @@ -60,7 +60,7 @@ export const WalletsNavWithWalletRender = function() { From 8775c79256381dbe6e71a1cf19125a12d57cbc92 Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Mon, 31 Jul 2017 21:15:20 +0300 Subject: [PATCH 28/58] Toggle visibility of Zero balance addresses on receive page --- .../dashboard/receiveCoin/receiveCoin.js | 22 ++++++++++++++++--- .../receiveCoin/receiveCoin.render.js | 15 +++++++++++++ react/src/translate/en.js | 3 ++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 9193512..e2a6c58 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -22,9 +22,11 @@ class ReceiveCoin extends React.Component { this.state = { openDropMenu: false, + hideZeroAdresses: false, }; this.openDropMenu = this.openDropMenu.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); + this.toggleVisibleAddress = this.toggleVisibleAddress.bind(this); } componentWillMount() { @@ -108,6 +110,12 @@ class ReceiveCoin extends React.Component { Store.dispatch(getNewKMDAddresses(this.props.coin, type)); } + toggleVisibleAddress() { + this.setState(Object.assign({}, this.state, { + hideZeroAdresses: !this.state.hideZeroAdresses, + })); + } + renderAddressList(type) { const _addresses = this.props.addresses; const _cache = this.props.cache; @@ -134,9 +142,17 @@ class ReceiveCoin extends React.Component { && _cache[_coin][address.address].getbalance.data.interest ? _cache[_coin][address.address].getbalance.data.interest : 'N/A'; } - items.push( - AddressItemRender.call(this, address, type) - ); + if (this.state.hideZeroAdresses) { + if (!this.hasNoAmount) { + items.push( + AddressItemRender.call(this, address, type) + ); + } + } else { + items.push( + AddressItemRender.call(this, address, type) + ); + } } return items; diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 108fb88..1d82e70 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -101,6 +101,21 @@ export const ReceiveCoinRender = function() {

      { translate('INDEX.RECEIVING_ADDRESS') }

  • +
    +
    + { translate('INDEX.TOGGLE_ZERO_ADDRESSES') } +
    + +
    { this.isNativeMode() ? diff --git a/react/src/translate/en.js b/react/src/translate/en.js index 4d5937c..1832b9b 100644 --- a/react/src/translate/en.js +++ b/react/src/translate/en.js @@ -252,7 +252,8 @@ export const _lang = { 'ACTIVATING': 'Activating', 'QRCODE': 'Show QR code', 'SCAN_QR_CODE': 'Scan QR Code', - 'SCAN_QRCODE_WEBCAM': 'Scan QR Code with webcam' + 'SCAN_QRCODE_WEBCAM': 'Scan QR Code with webcam', + 'TOGGLE_ZERO_ADDRESSES': 'Toggle empty addresses' }, 'ATOMIC': { 'RAW_OUTPUT': 'Raw Output', From 544e2c1469f27a8d271235d9cba49474d7c8448f Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Mon, 31 Jul 2017 22:40:06 +0300 Subject: [PATCH 29/58] Fixed a typo --- react/src/components/dashboard/receiveCoin/receiveCoin.js | 4 ++-- .../components/dashboard/receiveCoin/receiveCoin.render.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index e2a6c58..e3712bb 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -112,7 +112,7 @@ class ReceiveCoin extends React.Component { toggleVisibleAddress() { this.setState(Object.assign({}, this.state, { - hideZeroAdresses: !this.state.hideZeroAdresses, + hideZeroAddresses: !this.state.hideZeroAddresses, })); } @@ -142,7 +142,7 @@ class ReceiveCoin extends React.Component { && _cache[_coin][address.address].getbalance.data.interest ? _cache[_coin][address.address].getbalance.data.interest : 'N/A'; } - if (this.state.hideZeroAdresses) { + if (this.state.hideZeroAddresses) { if (!this.hasNoAmount) { items.push( AddressItemRender.call(this, address, type) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 1d82e70..5054347 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -110,7 +110,7 @@ export const ReceiveCoinRender = function() { - + { this.renderOPIDList() } diff --git a/react/src/components/dashboard/walletsProgress/walletsProgress.js b/react/src/components/dashboard/walletsProgress/walletsProgress.js index deafa93..f6ea680 100644 --- a/react/src/components/dashboard/walletsProgress/walletsProgress.js +++ b/react/src/components/dashboard/walletsProgress/walletsProgress.js @@ -112,8 +112,7 @@ class WalletsProgress extends React.Component { if (this.props.Dashboard.progress && this.props.Dashboard.progress.blocks) { - const syncPercentage = (parseFloat(parseInt(this.props.Dashboard.progress.blocks, 10) * 100 - / parseInt(this.props.Dashboard.progress.longestchain, 10)).toFixed(2) + '%').replace('NaN', 0); + const syncPercentage = (parseFloat(parseInt(this.props.Dashboard.progress.blocks, 10) * 100 / parseInt(this.props.Dashboard.progress.longestchain, 10)).toFixed(2) + '%').replace('NaN', 0); return SyncPercentageRender.call(this, syncPercentage); } From feb5f5a01a35dbeb62e1fa25021868961842f01e Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 2 Aug 2017 16:40:00 +0300 Subject: [PATCH 34/58] hide send btn if zero balance --- .../walletsBalance/walletsBalance.render.js | 2 +- .../dashboard/walletsNav/walletsNav.js | 36 +++++++++++++++++++ .../dashboard/walletsNav/walletsNav.render.js | 14 ++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js index 4d28a63..01a818b 100644 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js @@ -38,7 +38,7 @@ const WalletsBalanceRender = function() { - { Config.roundValues ? formatValue('round', this.renderBalance('transparent'), -6) : this.renderBalance('transparent') } { this.props.ActiveCoin.coin } + { Config.roundValues ? formatValue('round', this.renderBalance('transparent'), -6) : this.renderBalance('transparent') } diff --git a/react/src/components/dashboard/walletsNav/walletsNav.js b/react/src/components/dashboard/walletsNav/walletsNav.js index cfe7ddb..4b17767 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.js @@ -23,6 +23,7 @@ class WalletsNav extends React.Component { this.toggleSendReceiveCoinForms = this.toggleSendReceiveCoinForms.bind(this); this.toggleNativeWalletInfo = this.toggleNativeWalletInfo.bind(this); this.toggleNativeWalletTransactions = this.toggleNativeWalletTransactions.bind(this); + this.checkTotalBalance = this.checkTotalBalance.bind(this); } componentWillMount() { @@ -33,6 +34,41 @@ class WalletsNav extends React.Component { Store.dispatch(copyCoinAddress(address)); } + checkTotalBalance() { + let _balance = '0'; + const _mode = this.props.ActiveCoin.mode; + + if (_mode === 'full') { + _balance = this.props.ActiveCoin.balance || 0; + } else if (_mode === 'basilisk') { + if (this.props.ActiveCoin.cache) { + const _cache = this.props.ActiveCoin.cache; + const _coin = this.props.ActiveCoin.coin; + const _address = this.props.ActiveCoin.activeAddress; + + if (_address && + _cache[_coin] && + _cache[_coin][_address] && + _cache[_coin][_address].getbalance && + _cache[_coin][_address].getbalance.data && + (_cache[_coin][_address].getbalance.data.balance || + _cache[_coin][_address].getbalance.data.interest)) { + const _regBalance = _cache[_coin][_address].getbalance.data.balance ? _cache[_coin][_address].getbalance.data.balance : 0; + const _regInterest = _cache[_coin][_address].getbalance.data.interest ? _cache[_coin][_address].getbalance.data.interest : 0; + + _balance = _regBalance + _regInterest; + } + } + } else if (_mode === 'native') { + if (this.props.ActiveCoin.balance && + this.props.ActiveCoin.balance.total) { + _balance = this.props.ActiveCoin.balance.total; + } + } + + return _balance; + } + toggleSendReceiveCoinForms() { if (this.props.ActiveCoin.mode === 'native') { Store.dispatch( diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index e16a91e..67d43a7 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.render.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js @@ -52,12 +52,14 @@ export const WalletsNavWithWalletRender = function() { onClick={ this.props.ActiveCoin.mode !== 'native' ? this.toggleSendReceiveCoinForms : this.toggleNativeWalletTransactions }> { translate('INDEX.TRANSACTIONS') } - + { this.checkTotalBalance() > 0 && + + }
    { translate('INDEX.TIME') } { translate('INDEX.RESULT') }
    { this.isNativeMode() ? diff --git a/react/src/components/dashboard/walletsNative/walletsNative.render.js b/react/src/components/dashboard/walletsNative/walletsNative.render.js index 72ecaaf..15d5be5 100644 --- a/react/src/components/dashboard/walletsNative/walletsNative.render.js +++ b/react/src/components/dashboard/walletsNative/walletsNative.render.js @@ -16,7 +16,7 @@ const WalletsNativeRender = function() { style={{ 'backgroundImage': `url("assets/images/bg/${this.defaultBG()}_transparent_header_bg.png")` }}>
    1. - + From dbddf5110ae16c106802b962a0726ce0150a7fda Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 2 Aug 2017 20:06:26 +0300 Subject: [PATCH 36/58] disable log store update in prod --- react/src/actions/actions/addCoin.js | 42 ++-- react/src/actions/actions/addressBalance.js | 182 ++++++++++-------- react/src/actions/actions/atomic.js | 42 ++-- .../actions/actions/basiliskProcessAddress.js | 84 ++++---- react/src/actions/actions/createWallet.js | 42 ++-- react/src/actions/actions/dexCoins.js | 42 ++-- react/src/actions/actions/edexBalance.js | 72 ++++--- react/src/actions/actions/edexGetTx.js | 42 ++-- react/src/actions/actions/fullTxHistory.js | 42 ++-- react/src/actions/actions/getAddrByAccount.js | 42 ++-- react/src/actions/actions/iguanaHelpers.js | 42 ++-- react/src/actions/actions/logout.js | 42 ++-- react/src/actions/actions/nativeBalance.js | 42 ++-- react/src/actions/actions/nativeNewAddress.js | 42 ++-- react/src/actions/actions/nativeSend.js | 84 ++++---- react/src/actions/actions/nativeSyncInfo.js | 84 ++++---- react/src/actions/actions/nativeTxHistory.js | 42 ++-- react/src/actions/actions/notary.js | 84 ++++---- react/src/actions/actions/sendFullBasilisk.js | 168 +++++++++------- react/src/actions/actions/settings.js | 126 ++++++------ react/src/actions/actions/syncInfo.js | 42 ++-- react/src/actions/actions/walletAuth.js | 168 +++++++++------- 22 files changed, 913 insertions(+), 685 deletions(-) diff --git a/react/src/actions/actions/addCoin.js b/react/src/actions/actions/addCoin.js index bd11ef1..c34443b 100644 --- a/react/src/actions/actions/addCoin.js +++ b/react/src/actions/actions/addCoin.js @@ -97,14 +97,16 @@ export function addCoin(coin, mode, syncOnly, port, startupParams) { export function iguanaAddCoin(coin, mode, acData, port) { function _iguanaAddCoin(dispatch) { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaAddCoin', - 'type': 'post', - 'url': `http://127.0.0.1:${(port ? port : Config.iguanaCorePort)}`, - 'payload': acData, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaAddCoin', + 'type': 'post', + 'url': `http://127.0.0.1:${(port ? port : Config.iguanaCorePort)}`, + 'payload': acData, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${(port ? port : Config.iguanaCorePort)}`, { method: 'POST', @@ -112,11 +114,13 @@ export function iguanaAddCoin(coin, mode, acData, port) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( translate('TOASTR.FAILED_TO_ADDCOIN'), @@ -127,11 +131,13 @@ export function iguanaAddCoin(coin, mode, acData, port) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( addCoinResult( coin, diff --git a/react/src/actions/actions/addressBalance.js b/react/src/actions/actions/addressBalance.js index e0acd18..a420575 100644 --- a/react/src/actions/actions/addressBalance.js +++ b/react/src/actions/actions/addressBalance.js @@ -106,14 +106,16 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { } const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDAddressesNative', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDAddressesNative', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -137,11 +139,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDAddressesNative', @@ -152,11 +156,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } resolve(Config.cli.default && mode === 'native' ? json.result : json); }) } @@ -279,7 +285,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { Promise.all(result[1].map((_address, index) => { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - let ajaxDataToHex = `[\"${_address}\"]`; + let ajaxDataToHex = '["' + _address + '"]'; iguanaHashHex(ajaxDataToHex, dispatch) .then((hashHexJson) => { @@ -301,14 +307,16 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { 'hex': hashHexJson, }; } - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDAddressesNative+ZBalance', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDAddressesNative+ZBalance', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -341,11 +349,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDAddressesNative+ZBalance', @@ -359,11 +369,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { if (json && json.error) { resolve(0); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': json, + })); + } dispatch( triggerToaster( 'getKMDAddressesNative+ZBalance', @@ -382,11 +394,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { amount: json, type: 'private', }; - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } } }); }); @@ -435,14 +449,16 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { calcBalance(result, json[coin][currentAddress].refresh.data, dispatch, mode); } else { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDAddressesNative+Balance', - 'type': 'post', - 'url': `http://127.0.0.1:${(Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDAddressesNative+Balance', + 'type': 'post', + 'url': `http://127.0.0.1:${(Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${(Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}`, { method: 'POST', @@ -450,11 +466,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDAddressesNative+Balance', @@ -465,11 +483,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }) .then(response => response.json()) .then(function(json) { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } updatedCache.basilisk[coin][currentAddress].refresh = { 'data': json, 'status': 'done', @@ -487,14 +507,16 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { }) } else { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDAddressesNative+Balance', - 'type': 'post', - 'url': `http://127.0.0.1:${(Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDAddressesNative+Balance', + 'type': 'post', + 'url': `http://127.0.0.1:${(Config.useBasiliskInstance && mode === 'basilisk' ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -525,11 +547,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDAddressesNative+Balance', @@ -544,11 +568,13 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { mode === 'native') { json = json.result; } - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } calcBalance( result, json, diff --git a/react/src/actions/actions/atomic.js b/react/src/actions/actions/atomic.js index 8008e73..a6d5b73 100644 --- a/react/src/actions/actions/atomic.js +++ b/react/src/actions/actions/atomic.js @@ -9,14 +9,16 @@ import Config from '../../config'; export function atomic(payload) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'atomic', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'atomic', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -24,11 +26,13 @@ export function atomic(payload) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( payload.method, @@ -39,11 +43,13 @@ export function atomic(payload) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(atomicState(json)); }); } diff --git a/react/src/actions/actions/basiliskProcessAddress.js b/react/src/actions/actions/basiliskProcessAddress.js index 1a4445b..ec85708 100644 --- a/react/src/actions/actions/basiliskProcessAddress.js +++ b/react/src/actions/actions/basiliskProcessAddress.js @@ -17,14 +17,16 @@ export function checkAddressBasilisk(coin, address) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'checkAddressBasilisk', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'checkAddressBasilisk', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, { method: 'POST', @@ -32,11 +34,13 @@ export function checkAddressBasilisk(coin, address) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'checkAddressBasilisk', @@ -47,11 +51,13 @@ export function checkAddressBasilisk(coin, address) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(checkAddressBasiliskHandle(json)); }) } @@ -97,14 +103,16 @@ export function validateAddressBasilisk(coin, address) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'validateAddressBasilisk', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'validateAddressBasilisk', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, { method: 'POST', @@ -112,11 +120,13 @@ export function validateAddressBasilisk(coin, address) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'validateAddressBasilisk', @@ -127,11 +137,13 @@ export function validateAddressBasilisk(coin, address) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(validateAddressBasiliskHandle(json)); }) } diff --git a/react/src/actions/actions/createWallet.js b/react/src/actions/actions/createWallet.js index cde4df6..88fc4e2 100644 --- a/react/src/actions/actions/createWallet.js +++ b/react/src/actions/actions/createWallet.js @@ -42,14 +42,16 @@ export function createNewWallet(_passphrase) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'createNewWallet', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'createNewWallet', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -57,11 +59,13 @@ export function createNewWallet(_passphrase) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'createNewWallet', @@ -72,11 +76,13 @@ export function createNewWallet(_passphrase) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(createNewWalletState(json)); }) } diff --git a/react/src/actions/actions/dexCoins.js b/react/src/actions/actions/dexCoins.js index 8df3a0a..817ba99 100644 --- a/react/src/actions/actions/dexCoins.js +++ b/react/src/actions/actions/dexCoins.js @@ -17,14 +17,16 @@ export function getDexCoins() { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getDexCoins', - 'type': 'post', - 'url': Config.iguanaLessMode ? `http://127.0.0.1:${Config.agamaPort}/shepherd/InstantDEX/allcoins` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': _payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getDexCoins', + 'type': 'post', + 'url': Config.iguanaLessMode ? `http://127.0.0.1:${Config.agamaPort}/shepherd/InstantDEX/allcoins` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': _payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -46,11 +48,13 @@ export function getDexCoins() { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'Error getDexCoins', @@ -61,11 +65,13 @@ export function getDexCoins() { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(dashboardCoinsState(json)); }); } diff --git a/react/src/actions/actions/edexBalance.js b/react/src/actions/actions/edexBalance.js index f54c622..fcdeb55 100644 --- a/react/src/actions/actions/edexBalance.js +++ b/react/src/actions/actions/edexBalance.js @@ -17,14 +17,16 @@ export function iguanaEdexBalance(coin) { return dispatch => { if (coin) { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaEdexBalance', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': _payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaEdexBalance', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': _payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -32,11 +34,13 @@ export function iguanaEdexBalance(coin) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'Error iguanaEdexBalance', @@ -70,14 +74,16 @@ export function getDexBalance(coin, mode, addr) { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getDexBalance', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getDexBalance', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, { method: 'POST', @@ -85,11 +91,13 @@ export function getDexBalance(coin, mode, addr) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getDexBalance', @@ -101,11 +109,13 @@ export function getDexBalance(coin, mode, addr) { .then(response => response.json()) .then(json => { console.log(json); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } }) resolve(index); diff --git a/react/src/actions/actions/edexGetTx.js b/react/src/actions/actions/edexGetTx.js index aa5b987..c9561cb 100644 --- a/react/src/actions/actions/edexGetTx.js +++ b/react/src/actions/actions/edexGetTx.js @@ -17,14 +17,16 @@ export function edexGetTransaction(data, dispatch) { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'edexGetTransaction', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'edexGetTransaction', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -32,11 +34,13 @@ export function edexGetTransaction(data, dispatch) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'edexGetTransaction', @@ -47,11 +51,13 @@ export function edexGetTransaction(data, dispatch) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } resolve(json); }) }); diff --git a/react/src/actions/actions/fullTxHistory.js b/react/src/actions/actions/fullTxHistory.js index 124696a..64a8523 100644 --- a/react/src/actions/actions/fullTxHistory.js +++ b/react/src/actions/actions/fullTxHistory.js @@ -22,14 +22,16 @@ export function getFullTransactionsList(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getFullTransactionsList', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getFullTransactionsList', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -37,11 +39,13 @@ export function getFullTransactionsList(coin) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getFullTransactionsList', @@ -52,11 +56,13 @@ export function getFullTransactionsList(coin) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getNativeTxHistoryState(json)); }) } diff --git a/react/src/actions/actions/getAddrByAccount.js b/react/src/actions/actions/getAddrByAccount.js index 0ef1f52..2759224 100644 --- a/react/src/actions/actions/getAddrByAccount.js +++ b/react/src/actions/actions/getAddrByAccount.js @@ -37,14 +37,16 @@ export function getAddressesByAccount(coin, mode) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getAddressesByAccount', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getAddressesByAccount', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -52,11 +54,13 @@ export function getAddressesByAccount(coin, mode) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch(updateErrosStack('activeHandle')); dispatch( triggerToaster( @@ -68,11 +72,13 @@ export function getAddressesByAccount(coin, mode) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( getAddressesByAccountState( json, diff --git a/react/src/actions/actions/iguanaHelpers.js b/react/src/actions/actions/iguanaHelpers.js index a0eb8a9..bcae9eb 100644 --- a/react/src/actions/actions/iguanaHelpers.js +++ b/react/src/actions/actions/iguanaHelpers.js @@ -30,14 +30,16 @@ export function iguanaHashHex(data, dispatch) { resolve(true); } else { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaHashHex', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaHashHex', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -45,11 +47,13 @@ export function iguanaHashHex(data, dispatch) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'iguanaHashHex', @@ -60,11 +64,13 @@ export function iguanaHashHex(data, dispatch) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } resolve(json.hex); }) } diff --git a/react/src/actions/actions/logout.js b/react/src/actions/actions/logout.js index 63f4783..fe68c3f 100644 --- a/react/src/actions/actions/logout.js +++ b/react/src/actions/actions/logout.js @@ -39,14 +39,16 @@ function walletLock() { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'walletLock', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'walletLock', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -54,11 +56,13 @@ function walletLock() { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'walletLock', @@ -69,11 +73,13 @@ function walletLock() { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(logoutState(json)); dispatch(logoutResetAppState()); }) diff --git a/react/src/actions/actions/nativeBalance.js b/react/src/actions/actions/nativeBalance.js index 22ebef9..960e00f 100644 --- a/react/src/actions/actions/nativeBalance.js +++ b/react/src/actions/actions/nativeBalance.js @@ -42,14 +42,16 @@ export function getKMDBalanceTotal(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDBalanceTotal', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDBalanceTotal', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -72,11 +74,13 @@ export function getKMDBalanceTotal(coin) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDBalanceTotal', @@ -87,11 +91,13 @@ export function getKMDBalanceTotal(coin) { }) .then(response => response.json()) .then(function(json) { // TODO: figure out why komodod spits out "parse error" - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } if (json && !json.error) { dispatch(getNativeBalancesState(json)); diff --git a/react/src/actions/actions/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js index d41d213..4bd4088 100644 --- a/react/src/actions/actions/nativeNewAddress.js +++ b/react/src/actions/actions/nativeNewAddress.js @@ -49,14 +49,16 @@ export function getNewKMDAddresses(coin, pubpriv) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getNewKMDAddresses', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getNewKMDAddresses', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -85,11 +87,13 @@ export function getNewKMDAddresses(coin, pubpriv) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getNewKMDAddresses', @@ -103,11 +107,13 @@ export function getNewKMDAddresses(coin, pubpriv) { if (Config.cli.default) { json = json.result; } - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( handleGetNewKMDAddresses( pubpriv, diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index cde0cfe..0f788c8 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -48,14 +48,16 @@ export function sendNativeTx(coin, _payload) { } const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'sendNativeTx', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'sendNativeTx', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -98,11 +100,13 @@ export function sendNativeTx(coin, _payload) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'sendNativeTx', @@ -116,11 +120,13 @@ export function sendNativeTx(coin, _payload) { return _response; }) .then(function(json) { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } if (json.indexOf('"code":') > -1) { const _message = json.substring( @@ -209,14 +215,16 @@ export function getKMDOPID(opid, coin) { } const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getKMDOPID', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getKMDOPID', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -245,11 +253,13 @@ export function getKMDOPID(opid, coin) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getKMDOPID', @@ -263,11 +273,13 @@ export function getKMDOPID(opid, coin) { if (Config.cli.default) { json = json.result; } - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getKMDOPIDState(json)); }) }) diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index ed7c6cb..8260128 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -16,14 +16,16 @@ export function getSyncInfoNativeKMD(skipDebug) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getSyncInfoNativeKMD', - 'type': 'post', - 'url': Config.iguanaLessMode ? 'http://kmd.explorer.supernet.org/api/status?q=getInfo' : `http://127.0.0.1:${Config.iguanaCorePort}/api/dex/getinfo?userpass=tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}&symbol=${coin}`, - 'payload': '', - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getSyncInfoNativeKMD', + 'type': 'post', + 'url': Config.iguanaLessMode ? 'http://kmd.explorer.supernet.org/api/status?q=getInfo' : `http://127.0.0.1:${Config.iguanaCorePort}/api/dex/getinfo?userpass=tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}&symbol=${coin}`, + 'payload': '', + 'status': 'pending', + })); + } return fetch( Config.iguanaLessMode ? 'http://kmd.explorer.supernet.org/api/status?q=getInfo' : `http://127.0.0.1:${Config.iguanaCorePort}/api/dex/getinfo?userpass=tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}&symbol=${coin}`, { @@ -31,11 +33,13 @@ export function getSyncInfoNativeKMD(skipDebug) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getSyncInfoNativeKMD', @@ -46,11 +50,13 @@ export function getSyncInfoNativeKMD(skipDebug) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': Config.iguanaLessMode ? json.info : json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': Config.iguanaLessMode ? json.info : json, + })); + } dispatch(getSyncInfoNativeState({ 'remoteKMDNode': Config.iguanaLessMode ? json.info : json })); }) .then(function() { @@ -104,14 +110,16 @@ export function getSyncInfoNative(coin, skipDebug) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getSyncInfo', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getSyncInfo', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', body: JSON.stringify(payload), @@ -133,11 +141,13 @@ export function getSyncInfoNative(coin, skipDebug) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getSyncInfo', @@ -172,11 +182,13 @@ export function getSyncInfoNative(coin, skipDebug) { dispatch(getDebugLog('komodo', 1)); } - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( getSyncInfoNativeState( json, diff --git a/react/src/actions/actions/nativeTxHistory.js b/react/src/actions/actions/nativeTxHistory.js index 2bb72de..6724003 100644 --- a/react/src/actions/actions/nativeTxHistory.js +++ b/react/src/actions/actions/nativeTxHistory.js @@ -33,14 +33,16 @@ export function getNativeTxHistory(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getNativeTxHistory', - 'type': 'post', - 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getNativeTxHistory', + 'type': 'post', + 'url': Config.cli.default ? `http://127.0.0.1:${Config.agamaPort}/shepherd/cli` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -69,11 +71,13 @@ export function getNativeTxHistory(coin) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getNativeTxHistory', @@ -84,11 +88,13 @@ export function getNativeTxHistory(coin) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getNativeTxHistoryState(json)); }) } diff --git a/react/src/actions/actions/notary.js b/react/src/actions/actions/notary.js index d51d0ec..10f1c8a 100644 --- a/react/src/actions/actions/notary.js +++ b/react/src/actions/actions/notary.js @@ -23,25 +23,29 @@ function initNotaryNodesConSequence(nodes) { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': `initNotaryNodesConSequence+${node}`, - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': `initNotaryNodesConSequence+${node}`, + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${(Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort)}/api/dex/getinfo?userpass=${('tmpIgRPCUser@' + sessionStorage.getItem('IguanaRPCAuth'))}&symbol=${node}`, { method: 'GET', }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( `getInfoDexNode+${node}`, @@ -52,11 +56,13 @@ function initNotaryNodesConSequence(nodes) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( updateNotaryNodeConState( json, @@ -171,25 +177,29 @@ export function getDexNotaries(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getDexNotaries', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getDexNotaries', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.useBasiliskInstance ? Config.iguanaCorePort + 1 : Config.iguanaCorePort}`, { method: 'POST', body: JSON.stringify(payload), }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getDexNotaries', @@ -200,11 +210,13 @@ export function getDexNotaries(coin) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getDexNotariesState(json)); }) } diff --git a/react/src/actions/actions/sendFullBasilisk.js b/react/src/actions/actions/sendFullBasilisk.js index ee058fd..0abda10 100644 --- a/react/src/actions/actions/sendFullBasilisk.js +++ b/react/src/actions/actions/sendFullBasilisk.js @@ -25,14 +25,16 @@ export function sendToAddress(coin, _payload) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'sendToAddress', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'sendToAddress', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -40,11 +42,13 @@ export function sendToAddress(coin, _payload) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'sendToAddress', @@ -55,11 +59,13 @@ export function sendToAddress(coin, _payload) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(sendToAddressState(json, dispatch)); }) } @@ -81,14 +87,16 @@ export function sendFromAddress(coin, _payload) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'sendFromAddress', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'sendFromAddress', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -96,11 +104,13 @@ export function sendFromAddress(coin, _payload) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'sendFromAddress', @@ -111,11 +121,13 @@ export function sendFromAddress(coin, _payload) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(sendToAddressState(json, dispatch)); }) } @@ -140,14 +152,16 @@ export function iguanaUTXORawTX(data, dispatch) { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaUTXORawTX', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaUTXORawTX', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -155,11 +169,13 @@ export function iguanaUTXORawTX(data, dispatch) { }) .catch(function(error) { console.log(error); - dispatch => dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch => dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'iguanaUTXORawTX', @@ -170,11 +186,13 @@ export function iguanaUTXORawTX(data, dispatch) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } resolve(json); }) }); @@ -191,14 +209,16 @@ export function dexSendRawTX(data, dispatch) { return new Promise((resolve, reject) => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'dexSendRawTX', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'dexSendRawTX', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } fetch('http://127.0.0.1:' + Config.iguanaCorePort, { method: 'POST', @@ -206,11 +226,13 @@ export function dexSendRawTX(data, dispatch) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'dexSendRawTX', @@ -225,11 +247,13 @@ export function dexSendRawTX(data, dispatch) { return _response; }) .then(function(json) { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } resolve(json); }) }); diff --git a/react/src/actions/actions/settings.js b/react/src/actions/actions/settings.js index 126f10b..f38adfa 100644 --- a/react/src/actions/actions/settings.js +++ b/react/src/actions/actions/settings.js @@ -101,14 +101,16 @@ export function importPrivKey(wifKey) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'importPrivKey', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'importPrivKey', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -116,11 +118,13 @@ export function importPrivKey(wifKey) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'importPrivKey', @@ -131,11 +135,13 @@ export function importPrivKey(wifKey) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( parseImportPrivKeyResponse( json, @@ -200,14 +206,16 @@ export function getPeersList(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getPeersList', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getPeersList', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -215,11 +223,13 @@ export function getPeersList(coin) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getPeersList', @@ -230,11 +240,13 @@ export function getPeersList(coin) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getPeersListState(json, dispatch)); }) } @@ -316,14 +328,16 @@ export function addPeerNode(coin, ip) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'addPeerNode', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'addPeerNode', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -331,11 +345,13 @@ export function addPeerNode(coin, ip) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'addPeerNode', @@ -346,11 +362,13 @@ export function addPeerNode(coin, ip) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(addPeerNodeState(json, dispatch)); }) } diff --git a/react/src/actions/actions/syncInfo.js b/react/src/actions/actions/syncInfo.js index b24b944..53c87cf 100644 --- a/react/src/actions/actions/syncInfo.js +++ b/react/src/actions/actions/syncInfo.js @@ -31,14 +31,16 @@ export function getSyncInfo(coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'getSyncInfo', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'getSyncInfo', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -46,11 +48,13 @@ export function getSyncInfo(coin) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'getSyncInfo', @@ -65,11 +69,13 @@ export function getSyncInfo(coin) { return _response; }) .then(function(json) { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } if (json.indexOf('coin is busy processing') === -1) { dispatch(getSyncInfoState(json, dispatch)); } diff --git a/react/src/actions/actions/walletAuth.js b/react/src/actions/actions/walletAuth.js index aa5d767..31f2332 100644 --- a/react/src/actions/actions/walletAuth.js +++ b/react/src/actions/actions/walletAuth.js @@ -24,14 +24,16 @@ export function encryptWallet(_passphrase, cb, coin) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'encryptWallet', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'encryptWallet', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -39,11 +41,13 @@ export function encryptWallet(_passphrase, cb, coin) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'encryptWallet', @@ -55,11 +59,13 @@ export function encryptWallet(_passphrase, cb, coin) { .then(dispatch(walletPassphrase(_passphrase))) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch( cb.call( this, @@ -82,14 +88,16 @@ export function walletPassphrase(_passphrase) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'walletpassphrase', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'walletpassphrase', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -97,11 +105,13 @@ export function walletPassphrase(_passphrase) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'walletPassphrase', @@ -111,11 +121,13 @@ export function walletPassphrase(_passphrase) { ); }) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } }) } } @@ -132,14 +144,16 @@ export function iguanaWalletPassphrase(_passphrase) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaWalletPassphrase', - 'type': 'post', - 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': _payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaWalletPassphrase', + 'type': 'post', + 'url': `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': _payload, + 'status': 'pending', + })); + } return fetch(`http://127.0.0.1:${Config.iguanaCorePort}`, { method: 'POST', @@ -147,11 +161,13 @@ export function iguanaWalletPassphrase(_passphrase) { }) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch( triggerToaster( 'Error iguanaWalletPassphrase', @@ -162,11 +178,13 @@ export function iguanaWalletPassphrase(_passphrase) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(iguanaWalletPassphraseState(json, dispatch)); }); } @@ -181,14 +199,16 @@ export function iguanaActiveHandle(getMainAddress) { return dispatch => { const _timestamp = Date.now(); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'function': 'iguanaActiveHandle', - 'type': 'post', - 'url': Config.iguanaLessMode ? `http://127.0.0.1:${Config.agamaPort}/shepherd/SuperNET/activehandle` : `http://127.0.0.1:${Config.iguanaCorePort}`, - 'payload': _payload, - 'status': 'pending', - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'function': 'iguanaActiveHandle', + 'type': 'post', + 'url': Config.iguanaLessMode ? `http://127.0.0.1:${Config.agamaPort}/shepherd/SuperNET/activehandle` : `http://127.0.0.1:${Config.iguanaCorePort}`, + 'payload': _payload, + 'status': 'pending', + })); + } let _fetchConfig = { method: 'POST', @@ -210,11 +230,13 @@ export function iguanaActiveHandle(getMainAddress) { ) .catch(function(error) { console.log(error); - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'error', - 'response': error, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'error', + 'response': error, + })); + } dispatch(updateErrosStack('activeHandle')); dispatch( triggerToaster( @@ -226,11 +248,13 @@ export function iguanaActiveHandle(getMainAddress) { }) .then(response => response.json()) .then(json => { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + if (Config.debug) { + dispatch(logGuiHttp({ + 'timestamp': _timestamp, + 'status': 'success', + 'response': json, + })); + } dispatch(getMainAddress ? getMainAddressState(json) : iguanaActiveHandleState(json)); }); } From f3be7fa68d8ddf21f3448c149cd9c8410bad46f5 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 3 Aug 2017 11:28:16 +0300 Subject: [PATCH 37/58] tx info modal hide tabs; reset tab state on close --- react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js | 4 ++++ .../dashboard/walletsTxInfo/walletsTxInfo.render.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js index 3055c67..2ee27b8 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js @@ -15,6 +15,10 @@ class WalletsTxInfo extends React.Component { toggleTxInfoModal() { Store.dispatch(toggleDashboardTxInfoModal(false)); + + this.setState(Object.assign({}, this.state, { + activeTab: 0, + })); } openTab(tab) { diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js index 7b9643b..67fb416 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js @@ -22,7 +22,7 @@ const WalletsTxInfoRender = function(txInfo) {
    2. { this.isNativeMode() && -
    3. +
    4. this.openTab(1) }> Vjointsplits, Details @@ -30,7 +30,7 @@ const WalletsTxInfoRender = function(txInfo) { } { this.isNativeMode() && -
    5. +
    6. this.openTab(2) }> Hex From 8343a30ceee83bde29bcab61281fc5b8b6333aa4 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 3 Aug 2017 11:28:58 +0300 Subject: [PATCH 38/58] reduce setState to one call in walletsData compWillMount --- .../dashboard/walletsData/walletsData.js | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index f98e184..b94e4e6 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -249,15 +249,16 @@ class WalletsData extends React.Component { componentWillReceiveProps(props) { let historyToSplit; + let stateObj = {}; if (this.props && - this.props.ActiveCoin && - this.props.ActiveCoin.coin) { + this.props.ActiveCoin && + this.props.ActiveCoin.coin) { if (!this.state.currentAddress && this.props.ActiveCoin.activeAddress) { - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { currentAddress: this.props.ActiveCoin.activeAddress, - })); + }); } if (this.props.ActiveCoin.txhistory && @@ -273,22 +274,22 @@ class WalletsData extends React.Component { this.state.activePage * this.state.itemsPerPage ); - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { itemsList: historyToSplit, - })); + }); } } if (!historyToSplit && this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory === 'no data') { - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { itemsList: 'no data', - })); + }); } else if (!historyToSplit && this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory === 'loading') { - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { itemsList: 'loading', - })); + }); } else if ( // dirty first txhistory load workaround !historyToSplit && this.props.ActiveCoin.txhistory && @@ -302,11 +303,13 @@ class WalletsData extends React.Component { this.state.activePage * this.state.itemsPerPage ); - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { itemsList: historyToSplit, - })); + }); } } + + this.setState(Object.assign({}, this.state, stateObj)); } updateCurrentPage(page) { From 755f5dc1ec60428c8837232a5303073ad5a10d7a Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 3 Aug 2017 11:55:28 +0300 Subject: [PATCH 39/58] prevent tx re-sorting if txid a eq b --- .../walletsBalance/walletsBalance.render.js | 8 ++++---- .../components/dashboard/walletsData/walletsData.js | 12 ++++++++++-- react/src/util/sort.js | 5 ++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js index 01a818b..b375faf 100644 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.render.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.render.js @@ -37,7 +37,7 @@ const WalletsBalanceRender = function() { + title={ this.renderBalance('transparent') }> { Config.roundValues ? formatValue('round', this.renderBalance('transparent'), -6) : this.renderBalance('transparent') } @@ -57,7 +57,7 @@ const WalletsBalanceRender = function() { + title={ this.renderBalance('private') }> { Config.roundValues ? formatValue('round', this.renderBalance('private'), -6) : this.renderBalance('private') } @@ -78,7 +78,7 @@ const WalletsBalanceRender = function() { + title={ this.renderBalance('interest') }> { Config.roundValues ? formatValue('round', this.renderBalance('interest'), -6) : this.renderBalance('interest') } @@ -99,7 +99,7 @@ const WalletsBalanceRender = function() { + title={ this.renderBalance('total') }> { Config.roundValues ? formatValue('round', this.renderBalance('total'), -6) : this.renderBalance('total') } diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index b94e4e6..119a589 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -550,12 +550,20 @@ class WalletsData extends React.Component { if (_addresses.public[i].address === this.state.currentAddress) { if (_addresses.public[i].amount && _addresses.public[i].amount !== 'N/A') { - return _addresses.public[i].amount; + let _amount = _addresses.public[i].amount; + + if (_amount !== 'N/A') { + _amount = formatValue('round', _amount, -6); + } + + return _amount; } else { const address = _addresses.public[i].address; let _amount = _cache && _cache[_coin] && _cache[_coin][address] && _cache[_coin][address].getbalance.data && _cache[_coin][address].getbalance.data.balance ? _cache[_coin][address].getbalance.data.balance : 'N/A'; - _amount = formatValue('round', _amount, -6); + if (_amount !== 'N/A') { + _amount = formatValue('round', _amount, -6); + } return _amount; } diff --git a/react/src/util/sort.js b/react/src/util/sort.js index 5904c6b..c559c4e 100644 --- a/react/src/util/sort.js +++ b/react/src/util/sort.js @@ -1,8 +1,7 @@ export function sortByDate(data) { return data.sort(function(a, b) { - if (a.confirmations && - b.confirmations) { - return a.confirmations - b.confirmations; + if (a.txid === b.txid) { + return 1; } else { return a.confirmations - b.confirmations; } From d34a436cafe628d6cb828a91759dab0cc49f9b4d Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 3 Aug 2017 12:46:11 +0300 Subject: [PATCH 40/58] basilisk tx history address selector check mark --- .../dashboard/walletsData/walletsData.js | 24 ++++++++++++------- .../walletsData/walletsData.render.js | 2 +- .../walletsTxInfo/walletsTxInfo.render.js | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 119a589..74bdbb4 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -124,22 +124,24 @@ class WalletsData extends React.Component { } updateSocketsData(data) { + let stateObj = {}; + if (this.props.ActiveCoin.mode === 'basilisk') { if (data && data.message && data.message.shepherd.iguanaAPI && data.message.shepherd.iguanaAPI.totalStackLength) { - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { totalStackLength: data.message.shepherd.iguanaAPI.totalStackLength, - })); + }); } if (data && data.message && data.message.shepherd.iguanaAPI && data.message.shepherd.iguanaAPI.currentStackLength) { - this.setState(Object.assign({}, this.state, { + stateObj = Object.assign(stateObj, { currentStackLength: data.message.shepherd.iguanaAPI.currentStackLength, - })); + }); } if (data && data.message && @@ -148,6 +150,8 @@ class WalletsData extends React.Component { data.message.shepherd.status === 'done') { Store.dispatch(basiliskRefresh(false)); } + + this.setState(Object.assign({}, this.state, stateObj)); } } @@ -254,8 +258,8 @@ class WalletsData extends React.Component { if (this.props && this.props.ActiveCoin && this.props.ActiveCoin.coin) { - if (!this.state.currentAddress && - this.props.ActiveCoin.activeAddress) { + if ((!this.state.currentAddress && this.props.ActiveCoin.activeAddress) || + (this.state.currentAddress !== this.props.ActiveCoin.activeAddress)) { stateObj = Object.assign(stateObj, { currentAddress: this.props.ActiveCoin.activeAddress, }); @@ -307,9 +311,9 @@ class WalletsData extends React.Component { itemsList: historyToSplit, }); } - } - this.setState(Object.assign({}, this.state, stateObj)); + this.setState(Object.assign({}, this.state, stateObj)); + } } updateCurrentPage(page) { @@ -518,7 +522,9 @@ class WalletsData extends React.Component { } items.push( -
    7. +
    8. this.updateAddressSelection(address, type, _amount) }>    [ { _amount } { _coin } ]  { address } diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js index 13d77f3..c587b5e 100644 --- a/react/src/components/dashboard/walletsData/walletsData.render.js +++ b/react/src/components/dashboard/walletsData/walletsData.render.js @@ -131,7 +131,7 @@ export const AddressListRender = function() {
      diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js index 67fb416..4508d8c 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js @@ -51,7 +51,7 @@ const WalletsTxInfoRender = function(txInfo) {
    From 17124c74fd4ecfdf94d56db79a717c97e53e532b Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 3 Aug 2017 17:09:03 +0300 Subject: [PATCH 41/58] skip walletTxInfo tabs render --- .../walletsTxInfo/walletsTxInfo.render.js | 217 +++++++++--------- 1 file changed, 112 insertions(+), 105 deletions(-) diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js index 4508d8c..96b142c 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js @@ -22,7 +22,7 @@ const WalletsTxInfoRender = function(txInfo) { { this.isNativeMode() && -
  • +
  • this.openTab(1) }> Vjointsplits, Details @@ -30,7 +30,7 @@ const WalletsTxInfoRender = function(txInfo) { } { this.isNativeMode() && -
  • +
  • this.openTab(2) }> Hex @@ -45,117 +45,124 @@ const WalletsTxInfoRender = function(txInfo) {
    -
    -
  • { translate('TX_INFO.ADDRESS') } - { txInfo.address } + { this.props.ActiveCoin.mode === 'basilisk' ? this.props.ActiveCoin.activeAddress : txInfo.address }
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { this.isNativeMode() && + { this.state.activeTab === 0 && +
    +
    { translate('TX_INFO.ADDRESS') } - { this.props.ActiveCoin.mode === 'basilisk' ? this.props.ActiveCoin.activeAddress : txInfo.address } -
    { translate('TX_INFO.AMOUNT') } - { Config.roundValues ? formatValue('round', txInfo.amount, -10) : txInfo.amount } -
    { translate('TX_INFO.CATEGORY') } - { txInfo.category || txInfo.type } -
    { translate('TX_INFO.CONFIRMATIONS') } - { txInfo.confirmations } -
    blockhash - { txInfo.blockhash } -
    blocktime - { secondsToString(txInfo.blocktime || txInfo.timestamp) } -
    txid - { txInfo.txid } -
    + + + + + + + + + + + + + + + + + + { txInfo.blockhash && + + + + + } + { (txInfo.blocktime || txInfo.timestamp) && + + + + + } + + + + + { this.isNativeMode() && + + + + + } + { this.isNativeMode() && + + + + + } + { this.isNativeMode() && + + + + + } + +
    { translate('TX_INFO.ADDRESS') } + { this.props.ActiveCoin.mode === 'basilisk' ? this.props.ActiveCoin.activeAddress : txInfo.address } +
    { translate('TX_INFO.AMOUNT') } + { Config.roundValues ? formatValue('round', txInfo.amount, -10) : txInfo.amount } +
    { translate('TX_INFO.CATEGORY') } + { txInfo.category || txInfo.type } +
    { translate('TX_INFO.CONFIRMATIONS') } + { txInfo.confirmations } +
    blockhash + { txInfo.blockhash } +
    blocktime + { secondsToString(txInfo.blocktime || txInfo.timestamp) } +
    txid + { txInfo.txid } +
    walletconflicts + { txInfo.walletconflicts.length } +
    time + { secondsToString(txInfo.time) } +
    timereceived + { secondsToString(txInfo.timereceived) } +
    +
    + } + { this.state.activeTab === 1 && +
    + + - + - } - - { this.isNativeMode() && - + - } - - { this.isNativeMode() && - - - - - } - -
    walletconflictsvjoinsplit - { txInfo.walletconflicts.length } + { txInfo.vjoinsplit }
    timedetails - { secondsToString(txInfo.time) } + { txInfo.details }
    timereceived - { secondsToString(txInfo.timereceived) } -
    -
    - -
    - - - - - - - - - - - -
    vjoinsplit - { txInfo.vjoinsplit } -
    details - { txInfo.details } -
    -
    -
    - -
    - -
    - -
    + + +
    + } + { this.state.activeTab === 2 && +
    + +
    + } + { this.state.activeTab === 3 && +
    + +
    + }
    From 27f05218224c5c808c555ea55ada405f0266fe97 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 4 Aug 2017 00:00:54 +0300 Subject: [PATCH 42/58] skip tx history re-render if data is the same --- .../dashboard/coinTile/coinTileItem.js | 19 ++--------- .../dashboard/walletsData/walletsData.js | 34 +++++++++++++++---- .../walletsProgress/walletsProgress.js | 4 +-- .../walletsTxInfo/walletsTxInfo.render.js | 3 -- react/src/util/sort.js | 7 ++-- 5 files changed, 35 insertions(+), 32 deletions(-) diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js index cbf910b..bbf6c0b 100644 --- a/react/src/components/dashboard/coinTile/coinTileItem.js +++ b/react/src/components/dashboard/coinTile/coinTileItem.js @@ -25,10 +25,9 @@ import Config from '../../../config'; import CoinTileItemRender from './coinTileItem.render'; const BASILISK_CACHE_UPDATE_TIMEOUT = 240000; -const IGUNA_ACTIVE_HANDLE_TIMEOUT = 30000; -const IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE = 30000; +const IGUNA_ACTIVE_HANDLE_TIMEOUT = 3000; +const IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE = 15000; const NATIVE_MIN_SYNC_PERCENTAGE_THRESHOLD = 90; -let coinInitDataFetchInterval; class CoinTileItem extends React.Component { constructor(props) { @@ -108,20 +107,6 @@ class CoinTileItem extends React.Component { dashboardChangeActiveCoin(coin, mode) { if (coin !== this.props.ActiveCoin.coin) { - if (!this.props.ActiveCoin.coins[this.props.ActiveCoin.coin]) { - coinInitDataFetchInterval = setInterval(() => { - this.dispatchCoinActions(coin, mode); - - if ((mode === 'native' || mode === 'full') && this.props.Dashboard.progress) { - clearInterval(coinInitDataFetchInterval); - } - - if (mode === 'basilisk' && (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory !== 'loading') && this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] && JSON.parse(sessionStorage.getItem('IguanaActiveAccount'))[this.props.ActiveCoin.coin]) { - clearInterval(coinInitDataFetchInterval); - } - }, 500); - } - Store.dispatch( stopInterval( 'sync', diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 74bdbb4..6919c08 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -49,6 +49,7 @@ class WalletsData extends React.Component { currentStackLength: 0, totalStackLength: 0, useCache: true, + coin: null, }; this.updateInput = this.updateInput.bind(this); this.toggleBasiliskActionsMenu = this.toggleBasiliskActionsMenu.bind(this); @@ -278,9 +279,16 @@ class WalletsData extends React.Component { this.state.activePage * this.state.itemsPerPage ); - stateObj = Object.assign(stateObj, { - itemsList: historyToSplit, - }); + if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || (historyToSplit && + historyToSplit.length && + this.state.itemsList && + this.state.itemsList.length && + historyToSplit[0].txid !== this.state.itemsList[0].txid && + historyToSplit[historyToSplit.length - 1].txid !== this.state.itemsList[this.state.itemsList.length - 1].txid)) { + stateObj = Object.assign(stateObj, { + itemsList: historyToSplit, + }); + } } } @@ -307,12 +315,24 @@ class WalletsData extends React.Component { this.state.activePage * this.state.itemsPerPage ); - stateObj = Object.assign(stateObj, { - itemsList: historyToSplit, - }); + if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || (historyToSplit && + historyToSplit.length && + this.state.itemsList && + this.state.itemsList.length && + historyToSplit[0].txid !== this.state.itemsList[0].txid && + historyToSplit[historyToSplit.length - 1].txid !== this.state.itemsList[this.state.itemsList.length - 1].txid)) { + stateObj = Object.assign(stateObj, { + itemsList: historyToSplit, + }); + } } - this.setState(Object.assign({}, this.state, stateObj)); + stateObj = Object.assign(stateObj, { + coin: this.props.ActiveCoin.coin, + }); + if (Object.keys(stateObj).length) { + this.setState(Object.assign({}, this.state, stateObj)); + } } } diff --git a/react/src/components/dashboard/walletsProgress/walletsProgress.js b/react/src/components/dashboard/walletsProgress/walletsProgress.js index f6ea680..32134c2 100644 --- a/react/src/components/dashboard/walletsProgress/walletsProgress.js +++ b/react/src/components/dashboard/walletsProgress/walletsProgress.js @@ -93,7 +93,7 @@ class WalletsProgress extends React.Component { if (_progress && _progress[1]) { - return SyncPercentageRender.call(this, _progress[1].toFixed(2)); + return SyncPercentageRender.call(this, _progress[1] === 1000 ? 100 : _progress[1].toFixed(2)); } else { return LoadingBlocksRender.call(this); } @@ -113,7 +113,7 @@ class WalletsProgress extends React.Component { if (this.props.Dashboard.progress && this.props.Dashboard.progress.blocks) { const syncPercentage = (parseFloat(parseInt(this.props.Dashboard.progress.blocks, 10) * 100 / parseInt(this.props.Dashboard.progress.longestchain, 10)).toFixed(2) + '%').replace('NaN', 0); - return SyncPercentageRender.call(this, syncPercentage); + return SyncPercentageRender.call(this, syncPercentage === 1000 ? 100 : syncPercentage); } return LoadingBlocksRender.call(this); diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js index 96b142c..8afdd80 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.render.js @@ -20,7 +20,6 @@ const WalletsTxInfoRender = function(txInfo) { TxID Info - { this.isNativeMode() &&
  • this.openTab(1) }> @@ -28,7 +27,6 @@ const WalletsTxInfoRender = function(txInfo) {
  • } - { this.isNativeMode() &&
  • this.openTab(2) }> @@ -36,7 +34,6 @@ const WalletsTxInfoRender = function(txInfo) {
  • } -
  • this.openTab(3) }> Raw info diff --git a/react/src/util/sort.js b/react/src/util/sort.js index c559c4e..d7cf9d2 100644 --- a/react/src/util/sort.js +++ b/react/src/util/sort.js @@ -1,9 +1,10 @@ export function sortByDate(data) { return data.sort(function(a, b) { - if (a.txid === b.txid) { - return 1; - } else { + if (a.confirmations && + b.confirmations) { return a.confirmations - b.confirmations; + } else { + return 1; } }); } \ No newline at end of file From 356bf2c21fbd02c30b4074adf11e9a5858c6ec52 Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Fri, 4 Aug 2017 00:59:27 +0300 Subject: [PATCH 43/58] Adding missing argument --- react/src/components/dashboard/receiveCoin/receiveCoin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 34303a6..9f1c1dd 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -179,7 +179,7 @@ class ReceiveCoin extends React.Component { } if (this.state.hideZeroAddresses) { - if (!this.hasNoAmount) { + if (!this.hasNoAmount(address)) { items.push( AddressItemRender.call(this, address, type) ); From 0891d8708ecaf0b66c589c127cf904795ee4256e Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Fri, 4 Aug 2017 01:05:03 +0300 Subject: [PATCH 44/58] Show toggle button if balance is not 0 --- .../src/components/dashboard/receiveCoin/receiveCoin.render.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index de187d2..2ad384d 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -102,7 +102,7 @@ export const ReceiveCoinRender = function() {

    { translate('INDEX.RECEIVING_ADDRESS') }

    - { this.checkTotalBalance() === 0 && + { this.checkTotalBalance() !== 0 &&
    Date: Fri, 4 Aug 2017 07:18:11 +0300 Subject: [PATCH 45/58] trigger coin store fetch to load data --- react/src/components/dashboard/coinTile/coinTileItem.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js index bbf6c0b..62776bb 100644 --- a/react/src/components/dashboard/coinTile/coinTileItem.js +++ b/react/src/components/dashboard/coinTile/coinTileItem.js @@ -107,6 +107,9 @@ class CoinTileItem extends React.Component { dashboardChangeActiveCoin(coin, mode) { if (coin !== this.props.ActiveCoin.coin) { + Store.dispatch(dashboardChangeActiveCoin(coin, mode)); + this.dispatchCoinActions(coin, mode); // triggers fetch coin data from store if available + Store.dispatch( stopInterval( 'sync', @@ -121,8 +124,6 @@ class CoinTileItem extends React.Component { ) ); - Store.dispatch(dashboardChangeActiveCoin(coin, mode)); - if (mode === 'full') { const _iguanaActiveHandle = setInterval(() => { this.dispatchCoinActions(coin, mode); From d6bba8eb103e83384201d357b2d147d736582542 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 4 Aug 2017 21:52:37 +0300 Subject: [PATCH 46/58] sorting fix --- .../dashboard/coinTile/coinTileItem.js | 4 +- .../dashboard/settings/settings.render.js | 2 +- .../dashboard/walletsData/walletsData.js | 59 +++++++------------ .../walletsData/walletsData.render.js | 4 +- .../walletsProgress/walletsProgress.js | 5 +- .../walletsProgress/walletsProgress.render.js | 4 +- react/src/translate/en.js | 3 +- react/src/util/sort.js | 13 ++-- 8 files changed, 43 insertions(+), 51 deletions(-) diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js index 62776bb..e270774 100644 --- a/react/src/components/dashboard/coinTile/coinTileItem.js +++ b/react/src/components/dashboard/coinTile/coinTileItem.js @@ -108,7 +108,9 @@ class CoinTileItem extends React.Component { dashboardChangeActiveCoin(coin, mode) { if (coin !== this.props.ActiveCoin.coin) { Store.dispatch(dashboardChangeActiveCoin(coin, mode)); - this.dispatchCoinActions(coin, mode); // triggers fetch coin data from store if available + setTimeout(() => { + this.dispatchCoinActions(coin, mode); + }, 100); Store.dispatch( stopInterval( diff --git a/react/src/components/dashboard/settings/settings.render.js b/react/src/components/dashboard/settings/settings.render.js index aa17e53..065cfc4 100644 --- a/react/src/components/dashboard/settings/settings.render.js +++ b/react/src/components/dashboard/settings/settings.render.js @@ -77,7 +77,7 @@ export const AppInfoTabRender = function() { { translate('SETTINGS.NAME') }: { this.props.Settings.appInfo.releaseInfo.name }
    - { translate('SETTINGS.VERSION') }: { this.props.Settings.appInfo.releaseInfo.version } + { translate('SETTINGS.VERSION') }: { `${this.props.Settings.appInfo.releaseInfo.version.replace('version=', '')}-beta` }
    { translate('SETTINGS.APP_SESSION') }: { this.props.Settings.appInfo.appSession } diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 6919c08..867c214 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -50,6 +50,7 @@ class WalletsData extends React.Component { totalStackLength: 0, useCache: true, coin: null, + txhistory: null, }; this.updateInput = this.updateInput.bind(this); this.toggleBasiliskActionsMenu = this.toggleBasiliskActionsMenu.bind(this); @@ -152,7 +153,9 @@ class WalletsData extends React.Component { Store.dispatch(basiliskRefresh(false)); } - this.setState(Object.assign({}, this.state, stateObj)); + if (Object.keys(stateObj).length) { + this.setState(Object.assign({}, this.state, stateObj)); + } } } @@ -238,7 +241,7 @@ class WalletsData extends React.Component { } updateInput(e) { - let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory); + let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory, this.props.ActiveCoin.mode); historyToSplit = historyToSplit.slice(0, e.target.value); this.setState({ @@ -252,6 +255,16 @@ class WalletsData extends React.Component { Store.dispatch(toggleDashboardTxInfoModal(display, txIndex)); } + indexTxHistory(txhistoryArr) { + if (txhistoryArr.length > 1) { + for (let i = 0; i < txhistoryArr.length; i++) { + this.props.ActiveCoin.txhistory[i]['index'] = i + 1; + } + } + + return this.props.ActiveCoin.txhistory; + } + componentWillReceiveProps(props) { let historyToSplit; let stateObj = {}; @@ -270,26 +283,21 @@ class WalletsData extends React.Component { this.props.ActiveCoin.txhistory !== 'loading' && this.props.ActiveCoin.txhistory !== 'no data' && this.props.ActiveCoin.txhistory.length) { - if (!this.state.itemsList || - (this.state.itemsList && !this.state.itemsList.length) || - (props.ActiveCoin.txhistory !== this.props.ActiveCoin.txhistory)) { - historyToSplit = sortByDate(this.props.ActiveCoin.txhistory); + + historyToSplit = sortByDate(this.indexTxHistory(this.props.ActiveCoin.txhistory), this.props.ActiveCoin.mode === 'basilisk' ? 'index' : 'confirmations'); historyToSplit = historyToSplit.slice( (this.state.activePage - 1) * this.state.itemsPerPage, this.state.activePage * this.state.itemsPerPage ); - if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || (historyToSplit && - historyToSplit.length && - this.state.itemsList && - this.state.itemsList.length && - historyToSplit[0].txid !== this.state.itemsList[0].txid && - historyToSplit[historyToSplit.length - 1].txid !== this.state.itemsList[this.state.itemsList.length - 1].txid)) { + if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || ( + JSON.stringify(this.props.ActiveCoin.txhistory) !== JSON.stringify(this.state.txhistory))) { + stateObj = Object.assign(stateObj, { itemsList: historyToSplit, + txhistory: this.props.ActiveCoin.txhistory, }); } - } } if (!historyToSplit && @@ -302,29 +310,6 @@ class WalletsData extends React.Component { stateObj = Object.assign(stateObj, { itemsList: 'loading', }); - } else if ( // dirty first txhistory load workaround - !historyToSplit && - this.props.ActiveCoin.txhistory && - this.props.ActiveCoin.txhistory !== 'loading' && - this.props.ActiveCoin.txhistory !== 'no data' && - this.props.ActiveCoin.txhistory.length - ) { - historyToSplit = sortByDate(this.props.ActiveCoin.txhistory); - historyToSplit = historyToSplit.slice( - (this.state.activePage - 1) * this.state.itemsPerPage, - this.state.activePage * this.state.itemsPerPage - ); - - if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || (historyToSplit && - historyToSplit.length && - this.state.itemsList && - this.state.itemsList.length && - historyToSplit[0].txid !== this.state.itemsList[0].txid && - historyToSplit[historyToSplit.length - 1].txid !== this.state.itemsList[this.state.itemsList.length - 1].txid)) { - stateObj = Object.assign(stateObj, { - itemsList: historyToSplit, - }); - } } stateObj = Object.assign(stateObj, { @@ -337,7 +322,7 @@ class WalletsData extends React.Component { } updateCurrentPage(page) { - let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory); + let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory, this.props.ActiveCoin.mode); historyToSplit = historyToSplit.slice( (page - 1) * this.state.itemsPerPage, page * this.state.itemsPerPage diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js index c587b5e..97167ec 100644 --- a/react/src/components/dashboard/walletsData/walletsData.render.js +++ b/react/src/components/dashboard/walletsData/walletsData.render.js @@ -46,7 +46,7 @@ export const PaginationRender = function(paginationFrom, paginationTo) { const disableNextBtn = this.state.activePage >= Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage); return ( -
    +
    { translate('INDEX.SHOWING') }  @@ -117,7 +117,7 @@ export const AddressListRender = function() { if (isMultiPublicAddress || isMultiPrivateAddress) { return ( -
    +
    +
    +
    + + +
    this.toggle('jumblrSecretAddressShow') }> + Show address list +
    +
    +
    +
    + { this.state.jumblrSecretAddressShow && this.checkJumblrSecretAddressListLength('gen') && + + + + + + + + + { this._JumblrRenderSecretAddressList('gen') } + +
    + Address + + Wif +
    + } +
    +
    +
    +

    Use the form below to send funds to your jumblr deposit address.

    +

    You can also send funds to deposit address from an external service or another wallet.

    + +
    +
    -
    -
    + } + { this.state.jumblrMode === 'private' && +
    + +
    +
    + +
    +

    Enter your Jumblr passphrase you got previously during Public node configuration to import secret address.

    +

    Passphrase example: jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer.

    +

    The form below will "regenerate" Jumblr secret address based on passphrase provided.

    +

    After this final step expect to see funds processed and credited to your address after 2 days period.

    -
    -

    - { translate('JUMBLR.JSTATUS') } -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    { translate('JUMBLR.RESULT') } - -
    { translate('JUMBLR.DEPOSITED') }
    { translate('JUMBLR.PUB_TO_PRIV') }
    { translate('JUMBLR.PRIV_TO_PRIV') }
    { translate('JUMBLR.PRIV_TO_PUB') }
    { translate('JUMBLR.FINISHED') }
    { translate('JUMBLR.PENDING') }
    + { this.state.jumblrDepositAddressPBased && +
    + + this.passphraseOnChange(event) } + value={ this.state.jumblrPassphraseImport } /> +
    + } +
    Number of secret addresses
    +
    + +
    +
    + +
    +
    + + +
    this.toggle('jumblrSecretAddressShowImport') }> + Show address list +
    +
    +
    +
    + { this.state.jumblrSecretAddressShowImport && this.checkJumblrSecretAddressListLength('import') && + + + + + + + + + { this._JumblrRenderSecretAddressList('import') } + +
    + Address + + Wif +
    + } +
    +
    +
    +
    + +
    +
    -
    + }
    diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js index 03a1f3e..48816d0 100644 --- a/react/src/components/dashboard/navbar/navbar.render.js +++ b/react/src/components/dashboard/navbar/navbar.render.js @@ -57,11 +57,13 @@ const NavbarRender = function() { BarterDEX
  • -
  • - this.dashboardChangeSection('jumblr') }> - Jumblr - -
  • + { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && +
  • + this.dashboardChangeSection('jumblr') }> + Jumblr + +
  • + }
  • this.dashboardChangeSection('atomic') }> Atomic Explorer diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 1c13748..475e047 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -10,7 +10,8 @@ import { AddressActionsBasiliskModeRender, AddressActionsNonBasiliskModeRender, AddressItemRender, - ReceiveCoinRender + ReceiveCoinRender, + _ReceiveCoinTableRender } from './receiveCoin.render'; // TODO: implement balance/interest sorting @@ -28,6 +29,11 @@ class ReceiveCoin extends React.Component { this.handleClickOutside = this.handleClickOutside.bind(this); this.toggleVisibleAddress = this.toggleVisibleAddress.bind(this); this.checkTotalBalance = this.checkTotalBalance.bind(this); + this.ReceiveCoinTableRender = _ReceiveCoinTableRender.bind(this); + } + + ReceiveCoinTableRender() { + return this._ReceiveCoinTableRender(); } componentWillMount() { @@ -108,7 +114,7 @@ class ReceiveCoin extends React.Component { } getNewAddress(type) { - Store.dispatch(getNewKMDAddresses(this.props.coin, type)); + Store.dispatch(getNewKMDAddresses(this.props.coin, type, this.props.mode)); } toggleVisibleAddress() { diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 788988c..32a3324 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -61,105 +61,119 @@ export const AddressItemRender = function(address, type) { ); }; -export const ReceiveCoinRender = function() { +export const _ReceiveCoinTableRender = function() { return ( -
    -
    -
    -
    -
    -
    -
    - {this.isNativeMode() && - - } -

    { translate('INDEX.RECEIVING_ADDRESS') }

    -
    -
    - { this.checkTotalBalance() === 0 && -
    -
    - { translate('INDEX.TOGGLE_ZERO_ADDRESSES') } -
    -
    - ); + ); + } }; diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 867c214..ffedc92 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -428,13 +428,11 @@ class WalletsData extends React.Component { // TODO: add basilisk first run check, display no data if second run renderTxHistoryList() { if (this.state.itemsList === 'loading') { - if (!this.isNativeMode() || this.isFullySynced()) { - return ( - - { translate('INDEX.LOADING_HISTORY') }... - - ); - } + return ( + + { translate('INDEX.LOADING_HISTORY') }... + + ); } else if (this.state.itemsList === 'no data') { return ( diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js index d9a601e..3444ff8 100644 --- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js +++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js @@ -12,7 +12,9 @@ import Store from '../../../store'; import { AddressListRender, OASendUIRender, - WalletsNativeSendRender + WalletsNativeSendRender, + WalletsNativeSendFormRender, + _WalletsNativeSendFormRender } from './walletsNativeSend.render'; class WalletsNativeSend extends React.Component { @@ -37,6 +39,11 @@ class WalletsNativeSend extends React.Component { this.checkZAddressCount = this.checkZAddressCount.bind(this); this.setRecieverFromScan = this.setRecieverFromScan.bind(this); this.renderOPIDListCheck = this.renderOPIDListCheck.bind(this); + this.WalletsNativeSendFormRender = _WalletsNativeSendFormRender.bind(this); + } + + WalletsNativeSendFormRender() { + return this._WalletsNativeSendFormRender(); } componentWillMount() { @@ -344,7 +351,7 @@ class WalletsNativeSend extends React.Component { render() { if (this.props && this.props.ActiveCoin && - this.props.ActiveCoin.nativeActiveSection === 'send') { + (this.props.ActiveCoin.nativeActiveSection === 'send' || this.props.nativeActiveSection === 'send')) { return WalletsNativeSendRender.call(this); } diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js index fb9203f..d11ce18 100644 --- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js +++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js @@ -65,151 +65,163 @@ export const OASendUIRender = function() { ); }; -export const WalletsNativeSendRender = function() { +export const _WalletsNativeSendFormRender = function() { return ( -
    -
    -
    -
    -

    - { translate('INDEX.SEND') } { this.props.ActiveCoin.coin } -

    -
    -
    - -
    -
    - - { this.state.renderAddressDropdown && -
    -
    - - { this.renderAddressList() } -
    -
    - } - { this.renderOASendUI() } -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - { translate('INDEX.TOTAL') }:  - { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  - { this.props.ActiveCoin.coin } - -
    -
    - -
    -
    - +
    + { this.state.renderAddressDropdown && +
    +
    + + { this.renderAddressList() }
    + } + { this.renderOASendUI() } +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + { translate('INDEX.TOTAL') }:  + { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  + { this.props.ActiveCoin.coin } + +
    +
    + +
    +
    + ); +} - { this.renderOPIDListCheck() && -
    -
    -
    -
    -
    -
    -
    -

    - { translate('INDEX.OPERATIONS_STATUSES') } -

    -
    -
    - - - - - - - - - - - { this.renderOPIDList() } - - - - - - - - - -
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    +export const WalletsNativeSendRender = function() { + if (this.props.renderFormOnly) { + return ( +
    { this.WalletsNativeSendFormRender() }
    + ); + } else { + return ( +
    +
    +
    +
    +

    + { translate('INDEX.SEND') } { this.props.ActiveCoin.coin } +

    +
    +
    + +
    +
    + { this.WalletsNativeSendFormRender() } +
    +
    +
    + + { this.renderOPIDListCheck() && +
    +
    +
    +
    +
    +
    +
    +

    + { translate('INDEX.OPERATIONS_STATUSES') } +

    +
    +
    + + + + + + + + + + + { this.renderOPIDList() } + + + + + + + + + +
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    +
    -
    - } -
    - ); + } +
    + ); + } }; \ No newline at end of file diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index 7c79dad..b17f82d 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.render.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js @@ -26,7 +26,7 @@ export const WalletsNavWithWalletRender = function() {
    + style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30px' : '0') }}>
      { translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' } diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index 94eff32..c675967 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -94,7 +94,8 @@ body { display: block; } -.collapse-active { +.collapse-active, +.panel>:not(.panel-loading):not(.collapsing) { transition: height 0.3s ease-out; } @@ -738,4 +739,101 @@ select{ .page-header--native { height: 75px; +} + +#toast-container { + > div { + opacity: 1; + } +} + +/* jumblr */ +.jumblr { + p { + width: calc(100% - 100px); + } + .breadcrumb { + padding: 8px 30px; + position: relative; + top: 0; + } + .img-responsive { + position: absolute; + top: -28px; + right: 18px; + + .coin { + font-size: 30px; + position: relative; + left: -18px; + top: 4px; + } + .image { + width: 60px; + } + } + .header-easydex-section { + img { + max-width: inherit; + } + } + .copy-string-btn { + position: absolute; + right: 36px; + margin-top: -68px; + } + .btn-next { + position: absolute; + top: 60px; + right: 32px; + } + input.labelauty+label, + input.labelauty+label { + background: #d6d5d5; + color: #504e4e; + } + input.labelauty:checked+label { + color: #fff; + background-color: #3949ab; + } + input.labelauty + label:hover .labelauty-unchecked, + input.labelauty + label .labelauty-unchecked { + color: #504e4e; + } + .nofloat { + float: none; + display: inline-block; + padding-left: 0; + } +} + +.jumblr-mode-selector { + .nav-tabs { + li { + cursor: pointer; + + &.active { + > a { + cursor: pointer; + color: #fff; + background-color: #62a8ea; + border-color: transparent; + border-bottom-color: #62a8ea; + } + } + } + } + + .panel-heading { + background: #f3f3f3; + cursor: pointer; + } + .panel-title { + color: #676767; + } + .jumblr-addresses-list { + .col-xs-3 { + padding: 0; + } + } } \ No newline at end of file diff --git a/react/src/translate/en.js b/react/src/translate/en.js index df4a558..95af166 100644 --- a/react/src/translate/en.js +++ b/react/src/translate/en.js @@ -279,15 +279,15 @@ export const _lang = { }, 'JUMBLR': { 'NOTICE': 'EXPERIMENTAL TEST VERSION ONLY', - 'DESCRIPTION': 'Jumblr feature is very experimental and for now, is Only enabled for testing and debugging.' + + 'DESCRIPTION': 'Jumblr feature is very experimental and for now, is Only enabled for testing and debugging. ' + 'Please use the current version of Jumblr only with small amounts if you are participating in testing this feature.', 'NEED_NATIVE': 'Need Native Mode Komodo', 'TO_USE_JUMBLR': 'To use Jumblr feature, you need to activate Komodo in Native Mode.', 'IF_YOU_ALREADY_RUNNING': 'If you are already running Komodo in either Basilisk Mode or Full Mode, close the wallet and restart again to start Komodo In Native Mode.', 'THIS_SCREEN_DOESNT_REFRESH': 'This screen does not auto refresh. ' + - 'You will need to hit the Refresh button on the top right corner of the screen to get latest Jumblr data.', + 'You will need to hit the Refresh button on the top right corner of the screen to get latest Jumblr data.', 'FEW_SECURITY_NOTES': 'Few Security Notes for your Privacy and Anonymity of funds', - 'FEW_SECURITY_NOTES_DESC1': 'Jumblr addresses (BTC Jumbler and KMD Jumbler) addresses are your Private Addresses.', + 'FEW_SECURITY_NOTES_DESC1': 'Jumblr addresses addresses are your Private Addresses.', 'FEW_SECURITY_NOTES_DESC2': 'DO NOT SHARE your Jumblr addresses with anyone.', 'FEW_SECURITY_NOTES_DESC3': 'Jumblr addresses are like YOUR PASSWORD. Keep them safe, secure and hidden.', 'FEW_SECURITY_NOTES_DESC4': 'Only YOU should know your Jumblr Address. Nobody else.', diff --git a/react/src/util/crypto/gen/array.map.js b/react/src/util/crypto/gen/array.map.js new file mode 100755 index 0000000..d1b362f --- /dev/null +++ b/react/src/util/crypto/gen/array.map.js @@ -0,0 +1,57 @@ +// Array.prototype.map function is in the public domain. +// Production steps of ECMA-262, Edition 5, 15.4.4.19 +// Reference: http://es5.github.com/#x15.4.4.19 +if (!Array.prototype.map) { + Array.prototype.map = function (callback, thisArg) { + var T, A, k; + if (this == null) { + throw new TypeError(" this is null or not defined"); + } + // 1. Let O be the result of calling ToObject passing the |this| value as the argument. + var O = Object(this); + // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if ({}.toString.call(callback) != "[object Function]") { + throw new TypeError(callback + " is not a function"); + } + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (thisArg) { + T = thisArg; + } + // 6. Let A be a new array created as if by the expression new Array(len) where Array is + // the standard built-in constructor with that name and len is the value of len. + A = new Array(len); + // 7. Let k be 0 + k = 0; + // 8. Repeat, while k < len + while (k < len) { + var kValue, mappedValue; + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + // i. Let kValue be the result of calling the Get internal method of O with argument Pk. + kValue = O[k]; + // ii. Let mappedValue be the result of calling the Call internal method of callback + // with T as the this value and argument list containing kValue, k, and O. + mappedValue = callback.call(T, kValue, k, O); + // iii. Call the DefineOwnProperty internal method of A with arguments + // Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true}, + // and false. + // In browsers that support Object.defineProperty, use the following: + // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); + // For best browser support, use the following: + A[k] = mappedValue; + } + // d. Increase k by 1. + k++; + } + // 9. return A + return A; + }; +} \ No newline at end of file diff --git a/react/src/util/crypto/gen/biginteger.js b/react/src/util/crypto/gen/biginteger.js new file mode 100755 index 0000000..4d9c4ef --- /dev/null +++ b/react/src/util/crypto/gen/biginteger.js @@ -0,0 +1,1271 @@ +/*! +* Basic JavaScript BN library - subset useful for RSA encryption. v1.3 +* +* Copyright (c) 2005 Tom Wu +* All Rights Reserved. +* BSD License +* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE +* +* Copyright Stephan Thomas +* Copyright bitaddress.org +*/ + +(function () { + + // (public) Constructor function of Global BigInteger object + var BigInteger = window.BigInteger = function BigInteger(a, b, c) { + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); + }; + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = ((canary & 0xffffff) == 0xefcafe); + + // return new, unset BigInteger + function nbi() { return new BigInteger(null); } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; + } + if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; + } + else if (j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; + } + else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = ((1 << dbits) - 1); + BigInteger.prototype.DV = (1 << dbits); + + var BI_FP = 52; + BigInteger.prototype.FV = Math.pow(2, BI_FP); + BigInteger.prototype.F1 = BI_FP - dbits; + BigInteger.prototype.F2 = 2 * dbits - BI_FP; + + // Digit conversions + var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; + var BI_RC = new Array(); + var rr, vv; + rr = "0".charCodeAt(0); + for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; + rr = "a".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + rr = "A".charCodeAt(0); + for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + + function int2char(n) { return BI_RM.charAt(n); } + function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c == null) ? -1 : c; + } + + + + // return bigint initialized to value + function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + + + // returns bit length of the integer x + function nbits(x) { + var r = 1, t; + if ((t = x >>> 16) != 0) { x = t; r += 16; } + if ((t = x >> 8) != 0) { x = t; r += 8; } + if ((t = x >> 4) != 0) { x = t; r += 4; } + if ((t = x >> 2) != 0) { x = t; r += 2; } + if ((t = x >> 1) != 0) { x = t; r += 1; } + return r; + } + + + + + + + + // (protected) copy this to r + BigInteger.prototype.copyTo = function (r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + }; + + + // (protected) set from integer value x, -DV <= x < DV + BigInteger.prototype.fromInt = function (x) { + this.t = 1; + this.s = (x < 0) ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; + }; + + // (protected) set from string and radix + BigInteger.prototype.fromString = function (s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { this.fromRadix(s, b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while (--i >= 0) { + var x = (k == 8) ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) + this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = (x >> (this.DB - sh)); + } + else + this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + + // (protected) clamp off excess high words + BigInteger.prototype.clamp = function () { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; + }; + + // (protected) r = this << n*DB + BigInteger.prototype.dlShiftTo = function (n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; + }; + + // (protected) r = this >> n*DB + BigInteger.prototype.drShiftTo = function (n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; + }; + + + // (protected) r = this << n + BigInteger.prototype.lShiftTo = function (n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + }; + + + // (protected) r = this >> n + BigInteger.prototype.rShiftTo = function (n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { r.t = 0; return; } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); + }; + + + // (protected) r = this - a + BigInteger.prototype.subTo = function (a, r) { + var i = 0, c = 0, m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); + }; + + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyTo = function (a, r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); + }; + + + // (protected) r = this^2, r != this (HAC 14.16) + BigInteger.prototype.squareTo = function (r) { + var x = this.abs(); + var i = r.t = 2 * x.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); + }; + + + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + BigInteger.prototype.divRemTo = function (m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; + var i = r.t, j = i - ys, t = (q == null) ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); + }; + + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + BigInteger.prototype.invDigit = function () { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y; + }; + + + // (protected) true iff this is even + BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }; + + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + BigInteger.prototype.exp = function (e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); + }; + + + // (public) return string representation in given radix + BigInteger.prototype.toString = function (b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, d, m = false, r = "", i = this.t; + var p = this.DB - (i * this.DB) % k; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } + else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { p += this.DB; --i; } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : "0"; + }; + + + // (public) -this + BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; }; + + // (public) |this| + BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; }; + + // (public) return + if this > a, - if this < a, 0 if equal + BigInteger.prototype.compareTo = function (a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return (this.s < 0) ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; + } + + // (public) return the number of bits in "this" + BigInteger.prototype.bitLength = function () { + if (this.t <= 0) return 0; + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); + }; + + // (public) this mod a + BigInteger.prototype.mod = function (a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; + } + + // (public) this^e % m, 0 <= e < 2^32 + BigInteger.prototype.modPowInt = function (e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e, z); + }; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + + + + + + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + // Extended JavaScript BN functions, required for RSA private ops. + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { x >>= 16; r += 16; } + if ((x & 0xff) == 0) { x >>= 8; r += 8; } + if ((x & 0xf) == 0) { x >>= 4; r += 4; } + if ((x & 3) == 0) { x >>= 2; r += 2; } + if ((x & 1) == 0) ++r; + return r; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while (x != 0) { x &= x - 1; ++r; } + return r; + } + + var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; + var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + + + + // (protected) return x s.t. r^x < DV + BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); }; + + // (protected) convert to radix string + BigInteger.prototype.toRadix = function (b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + }; + + // (protected) convert from radix string + BigInteger.prototype.fromRadix = function (s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), mi = false, j = 0, w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); + }; + + // (protected) alternate constructor + BigInteger.prototype.fromNumber = function (a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0; + this.fromString(x, 256); + } + }; + + // (protected) r = this op a (bitwise) + BigInteger.prototype.bitwiseTo = function (a, op, r) { + var i, f, m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } + else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + }; + + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); + }; + + // (protected) this *= n, this >= 0, 1 < n < DV + BigInteger.prototype.dMultiply = function (n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + }; + + // (protected) this += n << w words, this >= 0 + BigInteger.prototype.dAddOffset = function (n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + }; + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyLowerTo = function (a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); + }; + + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyUpperTo = function (a, n, r) { + --n; + var i = r.t = this.t + a.t - n; + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); + }; + + // (protected) this % n, n < 2^26 + BigInteger.prototype.modInt = function (n) { + if (n <= 0) return 0; + var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; + }; + + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + BigInteger.prototype.millerRabin = function (t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; + }; + + + + // (public) + BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; }; + + // (public) return value as integer + BigInteger.prototype.intValue = function () { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } + else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + }; + + + // (public) return value as byte + BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; }; + + // (public) return value as short (assumes DB>=16) + BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; }; + + // (public) 0 if this == 0, 1 if this > 0 + BigInteger.prototype.signum = function () { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + }; + + + // (public) convert to bigendian byte array + BigInteger.prototype.toByteArray = function () { + var i = this.t, r = new Array(); + r[0] = this.s; + var p = this.DB - (i * this.DB) % 8, d, k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } + else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { p += this.DB; --i; } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; + }; + + BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); }; + BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; }; + BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; }; + + // (public) this & a + function op_and(x, y) { return x & y; } + BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; }; + + // (public) this | a + function op_or(x, y) { return x | y; } + BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; }; + + // (public) this ^ a + function op_xor(x, y) { return x ^ y; } + BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; }; + + // (public) this & ~a + function op_andnot(x, y) { return x & ~y; } + BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; }; + + // (public) ~this + BigInteger.prototype.not = function () { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + }; + + // (public) this << n + BigInteger.prototype.shiftLeft = function (n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r); + return r; + }; + + // (public) this >> n + BigInteger.prototype.shiftRight = function (n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r); + return r; + }; + + // (public) returns index of lowest 1-bit (or -1 if none) + BigInteger.prototype.getLowestSetBit = function () { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; + }; + + // (public) return number of set bits + BigInteger.prototype.bitCount = function () { + var r = 0, x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; + }; + + // (public) true iff nth bit is set + BigInteger.prototype.testBit = function (n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return (this.s != 0); + return ((this[j] & (1 << (n % this.DB))) != 0); + }; + + // (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { w >>= 1; --n; } + if ((i -= n) < 0) { i += this.DB; --j; } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; } + if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); t = r; r = r2; r2 = t; + if (--i < 0) { i = this.DB - 1; --j; } + } + } + return z.revert(r); + }; + + // (public) 1/this % m (HAC 14.61) + BigInteger.prototype.modInverse = function (m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); } + a.rShiftTo(1, a); + } + else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); } + c.rShiftTo(1, c); + } + else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } + else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if (d.compareTo(m) >= 0) return d.subtract(m); + if (d.signum() < 0) d.addTo(m, d); else return d; + if (d.signum() < 0) return d.add(m); else return d; + }; + + + // (public) this^e + BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); }; + + // (public) gcd(this,a) (HAC 14.54) + BigInteger.prototype.gcd = function (a) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { var t = x; x = y; y = t; } + var i = x.getLowestSetBit(), g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } + else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; + }; + + // (public) test primality with certainty >= 1-.5^t + BigInteger.prototype.isProbablePrime = function (t) { + var i, x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + }; + + + // JSBN-specific extension + + // (public) this^2 + BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; }; + + + // NOTE: BigInteger interfaces not implemented in jsbn: + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + + + // Copyright Stephan Thomas (start) --- // + // https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js + // BigInteger monkey patching + BigInteger.valueOf = nbv; + + /** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ + BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + if (ba.length) { + if (ba[0] == 0) { + ba = ba.slice(1); + } + return ba.map(function (v) { + return (v < 0) ? v + 256 : v; + }); + } else { + // Empty array, nothing to do + return ba; + } + }; + + /** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation and ignore leading zeros. + */ + BigInteger.fromByteArrayUnsigned = function (ba) { + if (!ba.length) { + return ba.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } + }; + + /** + * Converts big integer to signed byte representation. + * + * The format for this value uses a the most significant bit as a sign + * bit. If the most significant bit is already occupied by the + * absolute value, an extra byte is prepended and the sign bit is set + * there. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0x81 + * 127 => 0x7f + * -127 => 0xff + * 128 => 0x0080 + * -128 => 0x8080 + * 255 => 0x00ff + * -255 => 0x80ff + * 16300 => 0x3fac + * -16300 => 0xbfac + * 62300 => 0x00f35c + * -62300 => 0x80f35c + */ + BigInteger.prototype.toByteArraySigned = function () { + var val = this.abs().toByteArrayUnsigned(); + var neg = this.compareTo(BigInteger.ZERO) < 0; + + if (neg) { + if (val[0] & 0x80) { + val.unshift(0x80); + } else { + val[0] |= 0x80; + } + } else { + if (val[0] & 0x80) { + val.unshift(0x00); + } + } + + return val; + }; + + /** + * Parse a signed big integer byte representation. + * + * For details on the format please see BigInteger.toByteArraySigned. + */ + BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } + }; + // Copyright Stephan Thomas (end) --- // + + + + + // ****** REDUCTION ******* // + + // Modular reduction using "classic" algorithm + var Classic = window.Classic = function Classic(m) { this.m = m; } + Classic.prototype.convert = function (x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + }; + Classic.prototype.revert = function (x) { return x; }; + Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); }; + Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; + Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + + + + + + // Montgomery reduction + var Montgomery = window.Montgomery = function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + } + // xR mod m + Montgomery.prototype.convert = function (x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; + } + // x/R mod m + Montgomery.prototype.revert = function (x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + }; + // x = x/R mod m (HAC 14.32) + Montgomery.prototype.reduce = function (x) { + while (x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = "xy/R mod m"; x,y != r + Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; + // r = "x^2/R mod m"; x != r + Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + + + + + + // A "null" reducer + var NullExp = window.NullExp = function NullExp() { } + NullExp.prototype.convert = function (x) { return x; }; + NullExp.prototype.revert = function (x) { return x; }; + NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); }; + NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); }; + + + + + + // Barrett modular reduction + var Barrett = window.Barrett = function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + Barrett.prototype.convert = function (x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } + }; + Barrett.prototype.revert = function (x) { return x; }; + // x = x mod m (HAC 14.42) + Barrett.prototype.reduce = function (x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); + }; + // r = x*y mod m; x,y != r + Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; + // r = x^2 mod m; x != r + Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/bitcoin.js b/react/src/util/crypto/gen/bitcoin.js new file mode 100644 index 0000000..47dfdd5 --- /dev/null +++ b/react/src/util/crypto/gen/bitcoin.js @@ -0,0 +1,1974 @@ +// ----- Big Integer -----// +// (public) Constructor function of Global BigInteger object +var BigInteger = window.BigInteger = function BigInteger(a, b, c) { + if (a != null) + if ("number" == typeof a) this.fromNumber(a, b, c); + else if (b == null && "string" != typeof a) this.fromString(a, 256); + else this.fromString(a, b); +}; + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary & 0xffffff) == 0xefcafe); + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; +} +if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if (j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1 << dbits) - 1); +BigInteger.prototype.DV = (1 << dbits); + +var BI_FP = 52; +BigInteger.prototype.FV = Math.pow(2, BI_FP); +BigInteger.prototype.F1 = BI_FP - dbits; +BigInteger.prototype.F2 = 2 * dbits - BI_FP; + +// Digit conversions +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; +var BI_RC = new Array(); +var rr, vv; +rr = "0".charCodeAt(0); +for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; +rr = "a".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; +rr = "A".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + +function int2char(n) { return BI_RM.charAt(n); } +function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c == null) ? -1 : c; +} + + + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if ((t = x >>> 16) != 0) { x = t; r += 16; } + if ((t = x >> 8) != 0) { x = t; r += 8; } + if ((t = x >> 4) != 0) { x = t; r += 4; } + if ((t = x >> 2) != 0) { x = t; r += 2; } + if ((t = x >> 1) != 0) { x = t; r += 1; } + return r; +} + +// (protected) copy this to r +BigInteger.prototype.copyTo = function (r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +}; + +// (protected) set from integer value x, -DV <= x < DV +BigInteger.prototype.fromInt = function (x) { + this.t = 1; + this.s = (x < 0) ? -1 : 0; + if (x > 0) this[0] = x; + else if (x < -1) this[0] = x + this.DV; + else this.t = 0; +}; + +// (protected) set from string and radix +BigInteger.prototype.fromString = function (s, b) { + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 256) k = 8; // byte array + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else { this.fromRadix(s, b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while (--i >= 0) { + var x = (k == 8) ? s[i] & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if (sh == 0) + this[this.t++] = x; + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = (x >> (this.DB - sh)); + } + else + this[this.t - 1] |= x << sh; + sh += k; + if (sh >= this.DB) sh -= this.DB; + } + if (k == 8 && (s[0] & 0x80) != 0) { + this.s = -1; + if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + this.clamp(); + if (mi) BigInteger.ZERO.subTo(this, this); +}; + + +// (protected) clamp off excess high words +BigInteger.prototype.clamp = function () { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) --this.t; +}; + +// (protected) r = this << n*DB +BigInteger.prototype.dlShiftTo = function (n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; + for (i = n - 1; i >= 0; --i) r[i] = 0; + r.t = this.t + n; + r.s = this.s; +}; + +// (protected) r = this >> n*DB +BigInteger.prototype.drShiftTo = function (n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i]; + r.t = Math.max(this.t - n, 0); + r.s = this.s; +}; + +// (protected) r = this << n +BigInteger.prototype.lShiftTo = function (n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i; + for (i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (i = ds - 1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); +}; + +// (protected) r = this >> n +BigInteger.prototype.rShiftTo = function (n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { r.t = 0; return; } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; + r.t = this.t - ds; + r.clamp(); +}; + +// (protected) r = this - a +BigInteger.prototype.subTo = function (a, r) { + var i = 0, c = 0, m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c < -1) r[i++] = this.DV + c; + else if (c > 0) r[i++] = c; + r.t = i; + r.clamp(); +}; + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +BigInteger.prototype.multiplyTo = function (a, r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + r.s = 0; + r.clamp(); + if (this.s != a.s) BigInteger.ZERO.subTo(r, r); +}; + +// (protected) r = this^2, r != this (HAC 14.16) +BigInteger.prototype.squareTo = function (r) { + var x = this.abs(); + var i = r.t = 2 * x.t; + while (--i >= 0) r[i] = 0; + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + r.s = 0; + r.clamp(); +}; + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +BigInteger.prototype.divRemTo = function (m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) return; + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) q.fromInt(0); + if (r != null) this.copyTo(r); + return; + } + if (r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) return; + var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; + var i = r.t, j = i - ys, t = (q == null) ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0; + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) r.subTo(t, r); + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) BigInteger.ZERO.subTo(q, q); + } + r.t = ys; + r.clamp(); + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r); +}; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +BigInteger.prototype.invDigit = function () { + if (this.t < 1) return 0; + var x = this[0]; + if ((x & 1) == 0) return 0; + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y; +}; + +// (protected) true iff this is even +BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }; + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +BigInteger.prototype.exp = function (e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +}; + +// (public) return string representation in given radix +BigInteger.prototype.toString = function (b) { + if (this.s < 0) return "-" + this.negate().toString(b); + var k; + if (b == 16) k = 4; + else if (b == 8) k = 3; + else if (b == 2) k = 1; + else if (b == 32) k = 5; + else if (b == 4) k = 2; + else return this.toRadix(b); + var km = (1 << k) - 1, d, m = false, r = "", i = this.t; + var p = this.DB - (i * this.DB) % k; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } + else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { p += this.DB; --i; } + } + if (d > 0) m = true; + if (m) r += int2char(d); + } + } + return m ? r : "0"; +}; + +// (public) -this +BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; }; + +// (public) |this| +BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; }; + +// (public) return + if this > a, - if this < a, 0 if equal +BigInteger.prototype.compareTo = function (a) { + var r = this.s - a.s; + if (r != 0) return r; + var i = this.t; + r = i - a.t; + if (r != 0) return (this.s < 0) ? -r : r; + while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; + return 0; +} + +// (public) return the number of bits in "this" +BigInteger.prototype.bitLength = function () { + if (this.t <= 0) return 0; + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); +}; + +// (public) this mod a +BigInteger.prototype.mod = function (a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); + return r; +} + +// (public) this^e % m, 0 <= e < 2^32 +BigInteger.prototype.modPowInt = function (e, m) { + var z; + if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e, z); +}; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// Copyright (c) 2005-2009 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. +// Extended JavaScript BN functions, required for RSA private ops. +// Version 1.1: new BigInteger("0", 10) returns "proper" zero +// Version 1.2: square() API, isProbablePrime fix + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if (x == 0) return -1; + var r = 0; + if ((x & 0xffff) == 0) { x >>= 16; r += 16; } + if ((x & 0xff) == 0) { x >>= 8; r += 8; } + if ((x & 0xf) == 0) { x >>= 4; r += 4; } + if ((x & 3) == 0) { x >>= 2; r += 2; } + if ((x & 1) == 0) ++r; + return r; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while (x != 0) { x &= x - 1; ++r; } + return r; +} + +var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; +var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; + +// (protected) return x s.t. r^x < DV +BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); }; + +// (protected) convert to radix string +BigInteger.prototype.toRadix = function (b) { + if (b == null) b = 10; + if (this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; +}; + +// (protected) convert from radix string +BigInteger.prototype.fromRadix = function (s, b) { + this.fromInt(0); + if (b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b, cs), mi = false, j = 0, w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) BigInteger.ZERO.subTo(this, this); +}; + +// (protected) alternate constructor +BigInteger.prototype.fromNumber = function (a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) this.fromInt(1); + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + if (this.isEven()) this.dAddOffset(1, 0); // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0; + this.fromString(x, 256); + } +}; + +// (protected) r = this op a (bitwise) +BigInteger.prototype.bitwiseTo = function (a, op, r) { + var i, f, m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) r[i] = op(this[i], f); + r.t = this.t; + } + else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); +}; + +// (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c > 0) r[i++] = c; + else if (c < -1) r[i++] = this.DV + c; + r.t = i; + r.clamp(); +}; + +// (protected) this *= n, this >= 0, 1 < n < DV +BigInteger.prototype.dMultiply = function (n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); +}; + +// (protected) this += n << w words, this >= 0 +BigInteger.prototype.dAddOffset = function (n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +}; + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +BigInteger.prototype.multiplyLowerTo = function (a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) r[--i] = 0; + var j; + for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); + r.clamp(); +}; + + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +BigInteger.prototype.multiplyUpperTo = function (a, n, r) { + --n; + var i = r.t = this.t + a.t - n; + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0; + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + r.clamp(); + r.drShiftTo(1, r); +}; + +// (protected) this % n, n < 2^26 +BigInteger.prototype.modInt = function (n) { + if (n <= 0) return 0; + var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0; + if (this.t > 0) + if (d == 0) r = this[0] % n; + else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; + return r; +}; + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +BigInteger.prototype.millerRabin = function (t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) return false; + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for (var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) return false; + } + if (y.compareTo(n1) != 0) return false; + } + } + return true; +}; + +// (public) +BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; }; + +// (public) return value as integer +BigInteger.prototype.intValue = function () { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV; + else if (this.t == 0) return -1; + } + else if (this.t == 1) return this[0]; + else if (this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; +}; + +// (public) return value as byte +BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; }; + +// (public) return value as short (assumes DB>=16) +BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; }; + +// (public) 0 if this == 0, 1 if this > 0 +BigInteger.prototype.signum = function () { + if (this.s < 0) return -1; + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +}; + +// (public) convert to bigendian byte array +BigInteger.prototype.toByteArray = function () { + var i = this.t, r = new Array(); + r[0] = this.s; + var p = this.DB - (i * this.DB) % 8, d, k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) + r[k++] = d | (this.s << (this.DB - p)); + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } + else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { p += this.DB; --i; } + } + if ((d & 0x80) != 0) d |= -256; + if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; + if (k > 0 || d != this.s) r[k++] = d; + } + } + return r; +}; + +BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); }; +BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; }; +BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; }; + +// (public) this & a +function op_and(x, y) { return x & y; } +BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; }; + +// (public) this | a +function op_or(x, y) { return x | y; } +BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; }; + +// (public) this ^ a +function op_xor(x, y) { return x ^ y; } +BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; }; + +// (public) this & ~a +function op_andnot(x, y) { return x & ~y; } +BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; }; + +// (public) ~this +BigInteger.prototype.not = function () { + var r = nbi(); + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +}; + +// (public) this << n +BigInteger.prototype.shiftLeft = function (n) { + var r = nbi(); + if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r); + return r; +}; + +// (public) this >> n +BigInteger.prototype.shiftRight = function (n) { + var r = nbi(); + if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r); + return r; +}; + +// (public) returns index of lowest 1-bit (or -1 if none) +BigInteger.prototype.getLowestSetBit = function () { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]); + if (this.s < 0) return this.t * this.DB; + return -1; +}; + +// (public) return number of set bits +BigInteger.prototype.bitCount = function () { + var r = 0, x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); + return r; +}; + +// (public) true iff nth bit is set +BigInteger.prototype.testBit = function (n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) return (this.s != 0); + return ((this[j] & (1 << (n % this.DB))) != 0); +}; + +// (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + + var j = e.t - 1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km; + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); + } + + n = k; + while ((w & 1) == 0) { w >>= 1; --n; } + if ((i -= n) < 0) { i += this.DB; --j; } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; } + if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2, g[w], r); + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); t = r; r = r2; r2 = t; + if (--i < 0) { i = this.DB - 1; --j; } + } + } + return z.revert(r); +}; + +// (public) 1/this % m (HAC 14.61) +BigInteger.prototype.modInverse = function (m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); } + a.rShiftTo(1, a); + } + else if (!b.isEven()) b.subTo(m, b); + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); } + c.rShiftTo(1, c); + } + else if (!d.isEven()) d.subTo(m, d); + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) a.subTo(c, a); + b.subTo(d, b); + } + else { + v.subTo(u, v); + if (ac) c.subTo(a, c); + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if (d.compareTo(m) >= 0) return d.subtract(m); + if (d.signum() < 0) d.addTo(m, d); else return d; + if (d.signum() < 0) return d.add(m); else return d; +}; + +// (public) this^e +BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); }; + +// (public) gcd(this,a) (HAC 14.54) +BigInteger.prototype.gcd = function (a) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { var t = x; x = y; y = t; } + var i = x.getLowestSetBit(), g = y.getLowestSetBit(); + if (g < 0) return x; + if (i < g) g = i; + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } + else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) y.lShiftTo(g, y); + return y; +}; + +// (public) test primality with certainty >= 1-.5^t +BigInteger.prototype.isProbablePrime = function (t) { + var i, x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true; + return false; + } + if (x.isEven()) return false; + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i], j = i + 1; + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while (i < j) if (m % lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +}; + +// JSBN-specific extension + +// (public) this^2 +BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; }; +// NOTE: BigInteger interfaces not implemented in jsbn: +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) + +// Copyright Stephan Thomas (start) --- // +// https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js +// BigInteger monkey patching +BigInteger.valueOf = nbv; + +/** +* Returns a byte array representation of the big integer. +* +* This returns the absolute of the contained value in big endian +* form. A value of zero results in an empty array. +*/ +BigInteger.prototype.toByteArrayUnsigned = function () { + var ba = this.abs().toByteArray(); + if (ba.length) { + if (ba[0] == 0) { + ba = ba.slice(1); + } + return ba.map(function (v) { + return (v < 0) ? v + 256 : v; + }); + } else { + // Empty array, nothing to do + return ba; + } +}; + +/** +* Turns a byte array into a big integer. +* +* This function will interpret a byte array as a big integer in big +* endian notation and ignore leading zeros. +*/ +BigInteger.fromByteArrayUnsigned = function (ba) { + if (!ba.length) { + return ba.valueOf(0); + } else if (ba[0] & 0x80) { + // Prepend a zero so the BigInteger class doesn't mistake this + // for a negative integer. + return new BigInteger([0].concat(ba)); + } else { + return new BigInteger(ba); + } +}; + +/** +* Converts big integer to signed byte representation. +* +* The format for this value uses a the most significant bit as a sign +* bit. If the most significant bit is already occupied by the +* absolute value, an extra byte is prepended and the sign bit is set +* there. +* +* Examples: +* +* 0 => 0x00 +* 1 => 0x01 +* -1 => 0x81 +* 127 => 0x7f +* -127 => 0xff +* 128 => 0x0080 +* -128 => 0x8080 +* 255 => 0x00ff +* -255 => 0x80ff +* 16300 => 0x3fac +* -16300 => 0xbfac +* 62300 => 0x00f35c +* -62300 => 0x80f35c +*/ +BigInteger.prototype.toByteArraySigned = function () { + var val = this.abs().toByteArrayUnsigned(); + var neg = this.compareTo(BigInteger.ZERO) < 0; + + if (neg) { + if (val[0] & 0x80) { + val.unshift(0x80); + } else { + val[0] |= 0x80; + } + } else { + if (val[0] & 0x80) { + val.unshift(0x00); + } + } + + return val; +}; + +/** +* Parse a signed big integer byte representation. +* +* For details on the format please see BigInteger.toByteArraySigned. +*/ +BigInteger.fromByteArraySigned = function (ba) { + // Check for negative value + if (ba[0] & 0x80) { + // Remove sign bit + ba[0] &= 0x7f; + + return BigInteger.fromByteArrayUnsigned(ba).negate(); + } else { + return BigInteger.fromByteArrayUnsigned(ba); + } +}; +// Copyright Stephan Thomas (end) --- // + +// ****** REDUCTION ******* // + +// Modular reduction using "classic" algorithm +var Classic = window.Classic = function Classic(m) { this.m = m; } +Classic.prototype.convert = function (x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +}; +Classic.prototype.revert = function (x) { return x; }; +Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); }; +Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; +Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + +// Montgomery reduction +var Montgomery = window.Montgomery = function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; +} +// xR mod m +Montgomery.prototype.convert = function (x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); + return r; +} +// x/R mod m +Montgomery.prototype.revert = function (x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +}; +// x = x/R mod m (HAC 14.32) +Montgomery.prototype.reduce = function (x) { + while (x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); +}; +// r = "xy/R mod m"; x,y != r +Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; +// r = "x^2/R mod m"; x != r +Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + +// A "null" reducer +var NullExp = window.NullExp = function NullExp() { } +NullExp.prototype.convert = function (x) { return x; }; +NullExp.prototype.revert = function (x) { return x; }; +NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); }; +NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); }; + +// Barrett modular reduction +var Barrett = window.Barrett = function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} +Barrett.prototype.convert = function (x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); + else if (x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +}; +Barrett.prototype.revert = function (x) { return x; }; +// x = x mod m (HAC 14.42) +Barrett.prototype.reduce = function (x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); +}; +// r = x*y mod m; x,y != r +Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); }; +// r = x^2 mod m; x != r +Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); }; + +// ----- Bitcoin -----// +export let Bitcoin = {}; + +//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js +Bitcoin.Address = function (bytes) { +if ("string" == typeof bytes) { + bytes = Bitcoin.Address.decodeString(bytes); +} +this.hash = bytes; +}; + +/** +* Serialize this object as a standard currency address. +* +* Returns the address as a base58-encoded string in the standardized format. +*/ +Bitcoin.Address.prototype.toString = function () { +// Get a copy of the hash +var hash = this.hash.slice(0); + +// Version +hash.unshift('0x3c'); // KMD +var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true }); +var bytes = hash.concat(checksum.slice(0, 4)); +return Bitcoin.Base58.encode(bytes); +}; + +Bitcoin.Address.prototype.getHashBase64 = function () { +return Crypto.util.bytesToBase64(this.hash); +}; + +/** +* Parse a Bitcoin address contained in a string. +*/ +Bitcoin.Address.decodeString = function (string) { +var bytes = Bitcoin.Base58.decode(string); +var hash = bytes.slice(0, 21); +var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true }); + +if (checksum[0] != bytes[21] || + checksum[1] != bytes[22] || + checksum[2] != bytes[23] || + checksum[3] != bytes[24]) { + throw "Checksum validation failed!"; +} + +return hash; +}; + +Bitcoin.Base58 = { + alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/, + base: BigInteger.valueOf(58), + + /** + * Convert a byte array to a base58-encoded string. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + encode: function (input) { + var bi = BigInteger.fromByteArrayUnsigned(input); + var chars = []; + + while (bi.compareTo(B58.base) >= 0) { + var mod = bi.mod(B58.base); + chars.unshift(B58.alphabet[mod.intValue()]); + bi = bi.subtract(mod).divide(B58.base); + } + chars.unshift(B58.alphabet[bi.intValue()]); + + // Convert leading zeros too. + for (var i = 0; i < input.length; i++) { + if (input[i] == 0x00) { + chars.unshift(B58.alphabet[0]); + } else break; + } + + return chars.join(''); + }, + + /** + * Convert a base58-encoded string to a byte array. + * + * Written by Mike Hearn for BitcoinJ. + * Copyright (c) 2011 Google Inc. + * + * Ported to JavaScript by Stefan Thomas. + */ + decode: function (input) { + var bi = BigInteger.valueOf(0); + var leadingZerosNum = 0; + for (var i = input.length - 1; i >= 0; i--) { + var alphaIndex = B58.alphabet.indexOf(input[i]); + if (alphaIndex < 0) { + throw "Invalid character"; + } + bi = bi.add(BigInteger.valueOf(alphaIndex) + .multiply(B58.base.pow(input.length - 1 - i))); + + // This counts leading zero bytes + if (input[i] == "1") leadingZerosNum++; + else leadingZerosNum = 0; + } + var bytes = bi.toByteArrayUnsigned(); + + // Add leading zeros + while (leadingZerosNum-- > 0) bytes.unshift(0); + + return bytes; + } +}; + +const B58 = Bitcoin.Base58; + +Bitcoin.ECDSA = (function () { + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + var rng = new SecureRandom(); + + var P_OVER_FOUR = null; + + function implShamirsTrick(P, k, Q, l) { + var m = Math.max(k.bitLength(), l.bitLength()); + var Z = P.add2D(Q); + var R = P.curve.getInfinity(); + + for (var i = m - 1; i >= 0; --i) { + R = R.twice2D(); + + R.z = BigInteger.ONE; + + if (k.testBit(i)) { + if (l.testBit(i)) { + R = R.add2D(Z); + } else { + R = R.add2D(P); + } + } else { + if (l.testBit(i)) { + R = R.add2D(Q); + } + } + } + + return R; + }; + + var ECDSA = { + getBigRandom: function (limit) { + return new BigInteger(limit.bitLength(), rng) + .mod(limit.subtract(BigInteger.ONE)) + .add(BigInteger.ONE); + }, + sign: function (hash, priv) { + var d = priv; + var n = ecparams.getN(); + var e = BigInteger.fromByteArrayUnsigned(hash); + + do { + var k = ECDSA.getBigRandom(n); + var G = ecparams.getG(); + var Q = G.multiply(k); + var r = Q.getX().toBigInteger().mod(n); + } while (r.compareTo(BigInteger.ZERO) <= 0); + + var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); + + return ECDSA.serializeSig(r, s); + }, + + verify: function (hash, sig, pubkey) { + var r, s; + if (Bitcoin.Util.isArray(sig)) { + var obj = ECDSA.parseSig(sig); + r = obj.r; + s = obj.s; + } else if ("object" === typeof sig && sig.r && sig.s) { + r = sig.r; + s = sig.s; + } else { + throw "Invalid value for signature"; + } + + var Q; + if (pubkey instanceof ec.PointFp) { + Q = pubkey; + } else if (Bitcoin.Util.isArray(pubkey)) { + Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey); + } else { + throw "Invalid format for pubkey value, must be byte array or ec.PointFp"; + } + var e = BigInteger.fromByteArrayUnsigned(hash); + + return ECDSA.verifyRaw(e, r, s, Q); + }, + + verifyRaw: function (e, r, s, Q) { + var n = ecparams.getN(); + var G = ecparams.getG(); + + if (r.compareTo(BigInteger.ONE) < 0 || + r.compareTo(n) >= 0) + return false; + + if (s.compareTo(BigInteger.ONE) < 0 || + s.compareTo(n) >= 0) + return false; + + var c = s.modInverse(n); + + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // TODO(!!!): For some reason Shamir's trick isn't working with + // signed message verification!? Probably an implementation + // error! + //var point = implShamirsTrick(G, u1, Q, u2); + var point = G.multiply(u1).add(Q.multiply(u2)); + + var v = point.getX().toBigInteger().mod(n); + + return v.equals(r); + }, + + /** + * Serialize a signature into DER format. + * + * Takes two BigIntegers representing r and s and returns a byte array. + */ + serializeSig: function (r, s) { + var rBa = r.toByteArraySigned(); + var sBa = s.toByteArraySigned(); + + var sequence = []; + sequence.push(0x02); // INTEGER + sequence.push(rBa.length); + sequence = sequence.concat(rBa); + + sequence.push(0x02); // INTEGER + sequence.push(sBa.length); + sequence = sequence.concat(sBa); + + sequence.unshift(sequence.length); + sequence.unshift(0x30); // SEQUENCE + + return sequence; + }, + + /** + * Parses a byte array containing a DER-encoded signature. + * + * This function will return an object of the form: + * + * { + * r: BigInteger, + * s: BigInteger + * } + */ + parseSig: function (sig) { + var cursor; + if (sig[0] != 0x30) + throw new Error("Signature not a valid DERSequence"); + + cursor = 2; + if (sig[cursor] != 0x02) + throw new Error("First element in signature must be a DERInteger"); ; + var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + if (sig[cursor] != 0x02) + throw new Error("Second element in signature must be a DERInteger"); + var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]); + + cursor += 2 + sig[cursor + 1]; + + //if (cursor != sig.length) + // throw new Error("Extra bytes in signature"); + + var r = BigInteger.fromByteArrayUnsigned(rBa); + var s = BigInteger.fromByteArrayUnsigned(sBa); + + return { r: r, s: s }; + }, + + parseSigCompact: function (sig) { + if (sig.length !== 65) { + throw "Signature has the wrong length"; + } + + // Signature is prefixed with a type byte storing three bits of + // information. + var i = sig[0] - 27; + if (i < 0 || i > 7) { + throw "Invalid signature type"; + } + + var n = ecparams.getN(); + var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n); + var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n); + + return { r: r, s: s, i: i }; + }, + + /** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ + recoverPubKey: function (r, s, hash, i) { + // The recovery parameter i has two bits. + i = i & 3; + + // The less significant bit specifies whether the y coordinate + // of the compressed point is even or not. + var isYEven = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + var n = ecparams.getN(); + var G = ecparams.getG(); + var curve = ecparams.getCurve(); + var p = curve.getQ(); + var a = curve.getA().toBigInteger(); + var b = curve.getB().toBigInteger(); + + // We precalculate (p + 1) / 4 where p is if the field order + if (!P_OVER_FOUR) { + P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)); + } + + // 1.1 Compute x + var x = isSecondKey ? r.add(n) : r; + + // 1.3 Convert x to point + var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p); + var beta = alpha.modPow(P_OVER_FOUR, p); + + var xorOdd = beta.isEven() ? (i % 2) : ((i + 1) % 2); + // If beta is even, but y isn't or vice versa, then convert it, + // otherwise we're done and y == beta. + var y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta); + + // 1.4 Check that nR is at infinity + var R = new EllipticCurve.PointFp(curve, + curve.fromBigInteger(x), + curve.fromBigInteger(y)); + R.validate(); + + // 1.5 Compute e from M + var e = BigInteger.fromByteArrayUnsigned(hash); + var eNeg = BigInteger.ZERO.subtract(e).mod(n); + + // 1.6 Compute Q = r^-1 (sR - eG) + var rInv = r.modInverse(n); + var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv); + + Q.validate(); + if (!ECDSA.verifyRaw(e, r, s, Q)) { + throw "Pubkey recovery unsuccessful"; + } + + var pubKey = new Bitcoin.ECKey(); + pubKey.pub = Q; + return pubKey; + }, + + /** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ + calcPubkeyRecoveryParam: function (address, r, s, hash) { + for (var i = 0; i < 4; i++) { + try { + var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i); + if (pubkey.getBitcoinAddress().toString() == address) { + return i; + } + } catch (e) { } + } + throw "Unable to find valid recovery factor"; + } + }; + + return ECDSA; +})(); + +Bitcoin.ECKey = (function () { + var ECDSA = Bitcoin.ECDSA; + var ecparams = EllipticCurve.getSECCurveByName("secp256k1"); + var rng = new SecureRandom(); + + var ECKey = function (input) { + if (!input) { + // Generate new key + var n = ecparams.getN(); + this.priv = ECDSA.getBigRandom(n); + } else if (input instanceof BigInteger) { + // Input is a private key value + this.priv = input; + } else if (Bitcoin.Util.isArray(input)) { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(input); + } else if ("string" == typeof input) { + var bytes = null; + if (ECKey.isWalletImportFormat(input)) { + bytes = ECKey.decodeWalletImportFormat(input); + } else if (ECKey.isCompressedWalletImportFormat(input)) { + bytes = ECKey.decodeCompressedWalletImportFormat(input); + this.compressed = true; + } else if (ECKey.isMiniFormat(input)) { + bytes = Crypto.SHA256(input, { asBytes: true }); + } else if (ECKey.isHexFormat(input)) { + bytes = Crypto.util.hexToBytes(input); + } else if (ECKey.isBase64Format(input)) { + bytes = Crypto.util.base64ToBytes(input); + } + + if (ECKey.isBase6Format(input)) { + this.priv = new BigInteger(input, 6); + } else if (bytes == null || bytes.length != 32) { + this.priv = null; + } else { + // Prepend zero byte to prevent interpretation as negative integer + this.priv = BigInteger.fromByteArrayUnsigned(bytes); + } + } + + this.compressed = (this.compressed == undefined) ? !!ECKey.compressByDefault : this.compressed; + }; + + /** + * Whether public keys should be returned compressed by default. + */ + ECKey.compressByDefault = false; + + /** + * Set whether the public key should be returned compressed or not. + */ + ECKey.prototype.setCompressed = function (v) { + this.compressed = !!v; + if (this.pubPoint) this.pubPoint.compressed = this.compressed; + return this; + }; + + /* + * Return public key as a byte array in DER encoding + */ + ECKey.prototype.getPub = function () { + if (this.compressed) { + if (this.pubComp) return this.pubComp; + return this.pubComp = this.getPubPoint().getEncoded(1); + } else { + if (this.pubUncomp) return this.pubUncomp; + return this.pubUncomp = this.getPubPoint().getEncoded(0); + } + }; + + /** + * Return public point as ECPoint object. + */ + ECKey.prototype.getPubPoint = function () { + if (!this.pubPoint) { + this.pubPoint = ecparams.getG().multiply(this.priv); + this.pubPoint.compressed = this.compressed; + } + return this.pubPoint; + }; + + ECKey.prototype.getPubKeyHex = function () { + if (this.compressed) { + if (this.pubKeyHexComp) return this.pubKeyHexComp; + return this.pubKeyHexComp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase(); + } else { + if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp; + return this.pubKeyHexUncomp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase(); + } + }; + + /** + * Get the pubKeyHash for this key. + * + * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as + * a byte array. + */ + ECKey.prototype.getPubKeyHash = function () { + if (this.compressed) { + if (this.pubKeyHashComp) return this.pubKeyHashComp; + return this.pubKeyHashComp = Bitcoin.Util.sha256ripe160(this.getPub()); + } else { + if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp; + return this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160(this.getPub()); + } + }; + + ECKey.prototype.getBitcoinAddress = function () { + var hash = this.getPubKeyHash(); + var addr = new Bitcoin.Address(hash); + return addr.toString(); + }; + + /* + * Takes a public point as a hex string or byte array + */ + ECKey.prototype.setPub = function (pub) { + // byte array + if (Bitcoin.Util.isArray(pub)) { + pub = Crypto.util.bytesToHex(pub).toString().toUpperCase(); + } + var ecPoint = ecparams.getCurve().decodePointHex(pub); + this.setCompressed(ecPoint.compressed); + this.pubPoint = ecPoint; + return this; + }; + + // Sipa Private Key Wallet Import Format + ECKey.prototype.getBitcoinWalletImportFormat = function () { + var bytes = this.getBitcoinPrivateKeyByteArray(); + bytes.unshift('0xbc'); // prepend private key prefix // KMD + if (this.compressed) bytes.push(0x01); // append 0x01 byte for compressed format + var checksum = Crypto.SHA256(Crypto.SHA256(bytes, { asBytes: true }), { asBytes: true }); + bytes = bytes.concat(checksum.slice(0, 4)); + var privWif = Bitcoin.Base58.encode(bytes); + return privWif; + }; + + // Private Key Hex Format + ECKey.prototype.getBitcoinHexFormat = function () { + return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase(); + }; + + // Private Key Base64 Format + ECKey.prototype.getBitcoinBase64Format = function () { + return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray()); + }; + + ECKey.prototype.getBitcoinPrivateKeyByteArray = function () { + // Get a copy of private key as a byte array + var bytes = this.priv.toByteArrayUnsigned(); + // zero pad if private key is less than 32 bytes + while (bytes.length < 32) bytes.unshift(0x00); + return bytes; + }; + + ECKey.prototype.toString = function (format) { + format = format || ""; + if (format.toString().toLowerCase() == "base64" || format.toString().toLowerCase() == "b64") { + return this.getBitcoinBase64Format(); + } + // Wallet Import Format + else if (format.toString().toLowerCase() == "wif") { + return this.getBitcoinWalletImportFormat(); + } + else { + return this.getBitcoinHexFormat(); + } + }; + + ECKey.prototype.sign = function (hash) { + return ECDSA.sign(hash, this.priv); + }; + + ECKey.prototype.verify = function (hash, sig) { + return ECDSA.verify(hash, sig, this.getPub()); + }; + + /** + * Parse a wallet import format private key contained in a string. + */ + ECKey.decodeWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 33); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true }); + if (checksum[0] != bytes[33] || + checksum[1] != bytes[34] || + checksum[2] != bytes[35] || + checksum[3] != bytes[36]) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + // TODO: detect currency + if (version != janin.currency.privateKeyPrefix()) { + throw "Version " + version + " not supported!"; + } + return hash; + }; + + /** + * Parse a compressed wallet import format private key contained in a string. + */ + ECKey.decodeCompressedWalletImportFormat = function (privStr) { + var bytes = Bitcoin.Base58.decode(privStr); + var hash = bytes.slice(0, 34); + var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true }); + if (checksum[0] != bytes[34] || + checksum[1] != bytes[35] || + checksum[2] != bytes[36] || + checksum[3] != bytes[37]) { + throw "Checksum validation failed!"; + } + var version = hash.shift(); + // TODO: detect currency + if (version != janin.currency.privateKeyPrefix()) { + throw "Version " + version + " not supported!"; + } + hash.pop(); + return hash; + }; + + // 64 characters [0-9A-F] + ECKey.isHexFormat = function (key) { + key = key.toString(); + return /^[A-Fa-f0-9]{64}$/.test(key); + }; + + // 51 characters base58, always starts with a '5' + ECKey.isWalletImportFormat = function (key) { + key = key.toString(); + return janin.currency.WIF_RegEx().test(key); + }; + + // 52 characters base58 + ECKey.isCompressedWalletImportFormat = function (key) { + key = key.toString(); + return janin.currency.CWIF_RegEx().test(key); + }; + + // 44 characters + ECKey.isBase64Format = function (key) { + key = key.toString(); + return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key)); + }; + + // 99 characters, 1=1, if using dice convert 6 to 0 + ECKey.isBase6Format = function (key) { + key = key.toString(); + return (/^[012345]{99}$/.test(key)); + }; + + // 22, 26 or 30 characters, always starts with an 'S' + ECKey.isMiniFormat = function (key) { + key = key.toString(); + var validChars22 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test(key); + var validChars26 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test(key); + var validChars30 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test(key); + var testBytes = Crypto.SHA256(key + "?", { asBytes: true }); + + return ((testBytes[0] === 0x00 || testBytes[0] === 0x01) && (validChars22 || validChars26 || validChars30)); + }; + + return ECKey; +})(); + +//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js +// Bitcoin utility functions +Bitcoin.Util = { + /** + * Cross-browser compatibility version of Array.isArray. + */ + isArray: Array.isArray || function (o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }, + /** + * Create an array of a certain length filled with a specific value. + */ + makeFilledArray: function (len, val) { + var array = []; + var i = 0; + while (i < len) { + array[i++] = val; + } + return array; + }, + /** + * Turn an integer into a "var_int". + * + * "var_int" is a variable length integer used by Bitcoin's binary format. + * + * Returns a byte array. + */ + numToVarInt: function (i) { + if (i < 0xfd) { + // unsigned char + return [i]; + } else if (i <= 1 << 16) { + // unsigned short (LE) + return [0xfd, i >>> 8, i & 255]; + } else if (i <= 1 << 32) { + // unsigned int (LE) + return [0xfe].concat(Crypto.util.wordsToBytes([i])); + } else { + // unsigned long long (LE) + return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i])); + } + }, + /** + * Parse a Bitcoin value byte array, returning a BigInteger. + */ + valueToBigInt: function (valueBuffer) { + if (valueBuffer instanceof BigInteger) return valueBuffer; + + // Prepend zero byte to prevent interpretation as negative integer + return BigInteger.fromByteArrayUnsigned(valueBuffer); + }, + /** + * Format a Bitcoin value as a string. + * + * Takes a BigInteger or byte-array and returns that amount of Bitcoins in a + * nice standard formatting. + * + * Examples: + * 12.3555 + * 0.1234 + * 900.99998888 + * 34.00 + */ + formatValue: function (valueBuffer) { + var value = this.valueToBigInt(valueBuffer).toString(); + var integerPart = value.length > 8 ? value.substr(0, value.length - 8) : '0'; + var decimalPart = value.length > 8 ? value.substr(value.length - 8) : value; + while (decimalPart.length < 8) decimalPart = "0" + decimalPart; + decimalPart = decimalPart.replace(/0*$/, ''); + while (decimalPart.length < 2) decimalPart += "0"; + return integerPart + "." + decimalPart; + }, + /** + * Parse a floating point string as a Bitcoin value. + * + * Keep in mind that parsing user input is messy. You should always display + * the parsed value back to the user to make sure we understood his input + * correctly. + */ + parseValue: function (valueString) { + // TODO: Detect other number formats (e.g. comma as decimal separator) + var valueComp = valueString.split('.'); + var integralPart = valueComp[0]; + var fractionalPart = valueComp[1] || "0"; + while (fractionalPart.length < 8) fractionalPart += "0"; + fractionalPart = fractionalPart.replace(/^0+/g, ''); + var value = BigInteger.valueOf(parseInt(integralPart)); + value = value.multiply(BigInteger.valueOf(100000000)); + value = value.add(BigInteger.valueOf(parseInt(fractionalPart))); + return value; + }, + /** + * Calculate RIPEMD160(SHA256(data)). + * + * Takes an arbitrary byte array as inputs and returns the hash as a byte + * array. + */ + sha256ripe160: function (data) { + return Crypto.RIPEMD160(Crypto.SHA256(data, { asBytes: true }), { asBytes: true }); + }, + // double sha256 + dsha256: function (data) { + return Crypto.SHA256(Crypto.SHA256(data, { asBytes: true }), { asBytes: true }); + } +}; \ No newline at end of file diff --git a/react/src/util/crypto/gen/crypto-scrypt.js b/react/src/util/crypto/gen/crypto-scrypt.js new file mode 100755 index 0000000..01600f4 --- /dev/null +++ b/react/src/util/crypto/gen/crypto-scrypt.js @@ -0,0 +1,295 @@ +/* +* Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ +// https://github.com/cheongwy/node-scrypt-js +(function () { + + var MAX_VALUE = 2147483647; + var workerUrl = null; + + //function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) + /* + * N = Cpu cost + * r = Memory cost + * p = parallelization cost + * + */ + window.Crypto_scrypt = function (passwd, salt, N, r, p, dkLen, callback) { + if (N == 0 || (N & (N - 1)) != 0) throw Error("N must be > 0 and a power of 2"); + + if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large"); + if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large"); + + var PBKDF2_opts = { iterations: 1, hasher: Crypto.SHA256, asBytes: true }; + + var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts); + + try { + var i = 0; + var worksDone = 0; + var makeWorker = function () { + if (!workerUrl) { + var code = '(' + scryptCore.toString() + ')()'; + var blob; + try { + blob = new Blob([code], { type: "text/javascript" }); + } catch (e) { + window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + blob = new BlobBuilder(); + blob.append(code); + blob = blob.getBlob("text/javascript"); + } + workerUrl = URL.createObjectURL(blob); + } + var worker = new Worker(workerUrl); + worker.onmessage = function (event) { + var Bi = event.data[0], Bslice = event.data[1]; + worksDone++; + + if (i < p) { + worker.postMessage([N, r, p, B, i++]); + } + + var length = Bslice.length, destPos = Bi * 128 * r, srcPos = 0; + while (length--) { + B[destPos++] = Bslice[srcPos++]; + } + + if (worksDone == p) { + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + } + }; + return worker; + }; + var workers = [makeWorker(), makeWorker()]; + workers[0].postMessage([N, r, p, B, i++]); + if (p > 1) { + workers[1].postMessage([N, r, p, B, i++]); + } + } catch (e) { + window.setTimeout(function () { + scryptCore(); + callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts)); + }, 0); + } + + // using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use) + function scryptCore() { + var XY = [], V = []; + + if (typeof B === 'undefined') { + onmessage = function (event) { + var data = event.data; + var N = data[0], r = data[1], p = data[2], B = data[3], i = data[4]; + + var Bslice = []; + arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r); + smix(Bslice, 0, r, N, V, XY); + + postMessage([i, Bslice]); + }; + } else { + for (var i = 0; i < p; i++) { + smix(B, i * 128 * r, r, N, V, XY); + } + } + + function smix(B, Bi, r, N, V, XY) { + var Xi = 0; + var Yi = 128 * r; + var i; + + arraycopy32(B, Bi, XY, Xi, Yi); + + for (i = 0; i < N; i++) { + arraycopy32(XY, Xi, V, i * Yi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + for (i = 0; i < N; i++) { + var j = integerify(XY, Xi, r) & (N - 1); + blockxor(V, j * Yi, XY, Xi, Yi); + blockmix_salsa8(XY, Xi, Yi, r); + } + + arraycopy32(XY, Xi, B, Bi, Yi); + } + + function blockmix_salsa8(BY, Bi, Yi, r) { + var X = []; + var i; + + arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64); + + for (i = 0; i < 2 * r; i++) { + blockxor(BY, i * 64, X, 0, 64); + salsa20_8(X); + arraycopy32(X, 0, BY, Yi + (i * 64), 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64); + } + + for (i = 0; i < r; i++) { + arraycopy32(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64); + } + } + + function R(a, b) { + return (a << b) | (a >>> (32 - b)); + } + + function salsa20_8(B) { + var B32 = new Array(32); + var x = new Array(32); + var i; + + for (i = 0; i < 16; i++) { + B32[i] = (B[i * 4 + 0] & 0xff) << 0; + B32[i] |= (B[i * 4 + 1] & 0xff) << 8; + B32[i] |= (B[i * 4 + 2] & 0xff) << 16; + B32[i] |= (B[i * 4 + 3] & 0xff) << 24; + } + + arraycopy(B32, 0, x, 0, 16); + + for (i = 8; i > 0; i -= 2) { + x[4] ^= R(x[0] + x[12], 7); x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); x[0] ^= R(x[12] + x[8], 18); + x[9] ^= R(x[5] + x[1], 7); x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); x[5] ^= R(x[1] + x[13], 18); + x[14] ^= R(x[10] + x[6], 7); x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); x[10] ^= R(x[6] + x[2], 18); + x[3] ^= R(x[15] + x[11], 7); x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); x[15] ^= R(x[11] + x[7], 18); + x[1] ^= R(x[0] + x[3], 7); x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); x[0] ^= R(x[3] + x[2], 18); + x[6] ^= R(x[5] + x[4], 7); x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); x[5] ^= R(x[4] + x[7], 18); + x[11] ^= R(x[10] + x[9], 7); x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); x[10] ^= R(x[9] + x[8], 18); + x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); x[15] ^= R(x[14] + x[13], 18); + } + + for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i]; + + for (i = 0; i < 16; i++) { + var bi = i * 4; + B[bi + 0] = (B32[i] >> 0 & 0xff); + B[bi + 1] = (B32[i] >> 8 & 0xff); + B[bi + 2] = (B32[i] >> 16 & 0xff); + B[bi + 3] = (B32[i] >> 24 & 0xff); + } + } + + function blockxor(S, Si, D, Di, len) { + var i = len >> 6; + while (i--) { + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++]; + } + } + + function integerify(B, bi, r) { + var n; + + bi += (2 * r - 1) * 64; + + n = (B[bi + 0] & 0xff) << 0; + n |= (B[bi + 1] & 0xff) << 8; + n |= (B[bi + 2] & 0xff) << 16; + n |= (B[bi + 3] & 0xff) << 24; + + return n; + } + + function arraycopy(src, srcPos, dest, destPos, length) { + while (length--) { + dest[destPos++] = src[srcPos++]; + } + } + + function arraycopy32(src, srcPos, dest, destPos, length) { + var i = length >> 5; + while (i--) { + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++]; + } + } + } // scryptCore + }; // window.Crypto_scrypt +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.aes.js b/react/src/util/crypto/gen/cryptojs.aes.js new file mode 100755 index 0000000..dfcba32 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.aes.js @@ -0,0 +1,407 @@ +/*! +* Crypto-JS v2.5.4 AES.js +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +*/ +(function () { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8; + + // Precomputed SBOX + var SBOX = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]; + + // Compute inverse SBOX lookup table + for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; + + // Compute multiplication in GF(2^8) lookup tables + var MULT2 = [], + MULT3 = [], + MULT9 = [], + MULTB = [], + MULTD = [], + MULTE = []; + + function xtime(a, b) { + for (var result = 0, i = 0; i < 8; i++) { + if (b & 1) result ^= a; + var hiBitSet = a & 0x80; + a = (a << 1) & 0xFF; + if (hiBitSet) a ^= 0x1b; + b >>>= 1; + } + return result; + } + + for (var i = 0; i < 256; i++) { + MULT2[i] = xtime(i, 2); + MULT3[i] = xtime(i, 3); + MULT9[i] = xtime(i, 9); + MULTB[i] = xtime(i, 0xB); + MULTD[i] = xtime(i, 0xD); + MULTE[i] = xtime(i, 0xE); + } + + // Precomputed RCon lookup + var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + // Inner state + var state = [[], [], [], []], + keylength, + nrounds, + keyschedule; + + var AES = C.AES = { + + /** + * Public API + */ + + encrypt: function (message, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if message is a string + m = ( + message.constructor == String ? + UTF8.stringToBytes(message) : + message + ), + + // Generate random IV + iv = options.iv || util.randomBytes(AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password + ); + + // Encrypt + AES._init(k); + mode.encrypt(AES, m, iv); + + // Return ciphertext + m = options.iv ? m : iv.concat(m); + return (options && options.asBytes) ? m : util.bytesToBase64(m); + + }, + + decrypt: function (ciphertext, password, options) { + + options = options || {}; + + // Determine mode + var mode = options.mode || new C.mode.OFB; + + // Allow mode to override options + if (mode.fixOptions) mode.fixOptions(options); + + var + + // Convert to bytes if ciphertext is a string + c = ( + ciphertext.constructor == String ? + util.base64ToBytes(ciphertext) : + ciphertext + ), + + // Separate IV and message + iv = options.iv || c.splice(0, AES._blocksize * 4), + + // Generate key + k = ( + password.constructor == String ? + // Derive key from pass-phrase + C.PBKDF2(password, iv, 32, { asBytes: true }) : + // else, assume byte array representing cryptographic key + password + ); + + // Decrypt + AES._init(k); + mode.decrypt(AES, c, iv); + + // Return plaintext + return (options && options.asBytes) ? c : UTF8.bytesToString(c); + + }, + + + /** + * Package private methods and properties + */ + + _blocksize: 4, + + _encryptblock: function (m, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = m[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; + state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; + state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; + state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; + + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[round * 4 + col][row]; + } + + } + + // Sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = SBOX[state[row][col]]; + } + + // Shift rows + state[1].push(state[1].shift()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].unshift(state[3].pop()); + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + m[offset + col * 4 + row] = state[row][col]; + } + + }, + + _decryptblock: function (c, offset) { + + // Set input + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = c[offset + col * 4 + row]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[nrounds * 4 + col][row]; + } + + for (var round = 1; round < nrounds; round++) { + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row]; + } + + // Inv mix columns + for (var col = 0; col < 4; col++) { + + var s0 = state[0][col], + s1 = state[1][col], + s2 = state[2][col], + s3 = state[3][col]; + + state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; + state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; + state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; + state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; + + } + + } + + // Inv shift rows + state[1].unshift(state[1].pop()); + state[2].push(state[2].shift()); + state[2].push(state[2].shift()); + state[3].push(state[3].shift()); + + // Inv sub bytes + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] = INVSBOX[state[row][col]]; + } + + // Add round key + for (var row = 0; row < 4; row++) { + for (var col = 0; col < 4; col++) + state[row][col] ^= keyschedule[col][row]; + } + + // Set output + for (var row = 0; row < AES._blocksize; row++) { + for (var col = 0; col < 4; col++) + c[offset + col * 4 + row] = state[row][col]; + } + + }, + + + /** + * Private methods + */ + + _init: function (k) { + keylength = k.length / 4; + nrounds = keylength + 6; + AES._keyexpansion(k); + }, + + // Generate a key schedule + _keyexpansion: function (k) { + + keyschedule = []; + + for (var row = 0; row < keylength; row++) { + keyschedule[row] = [ + k[row * 4], + k[row * 4 + 1], + k[row * 4 + 2], + k[row * 4 + 3] + ]; + } + + for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) { + + var temp = [ + keyschedule[row - 1][0], + keyschedule[row - 1][1], + keyschedule[row - 1][2], + keyschedule[row - 1][3] + ]; + + if (row % keylength == 0) { + + // Rot word + temp.push(temp.shift()); + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + temp[0] ^= RCON[row / keylength]; + + } else if (keylength > 6 && row % keylength == 4) { + + // Sub word + temp[0] = SBOX[temp[0]]; + temp[1] = SBOX[temp[1]]; + temp[2] = SBOX[temp[2]]; + temp[3] = SBOX[temp[3]]; + + } + + keyschedule[row] = [ + keyschedule[row - keylength][0] ^ temp[0], + keyschedule[row - keylength][1] ^ temp[1], + keyschedule[row - keylength][2] ^ temp[2], + keyschedule[row - keylength][3] ^ temp[3] + ]; + + } + + } + + }; + +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.blockmodes.js b/react/src/util/crypto/gen/cryptojs.blockmodes.js new file mode 100755 index 0000000..e0de9e6 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.blockmodes.js @@ -0,0 +1,410 @@ +/*! +* Crypto-JS 2.5.4 BlockModes.js +* contribution from Simon Greatrix +*/ + +(function (C) { + + // Create pad namespace + var C_pad = C.pad = {}; + + // Calculate the number of padding bytes required. + function _requiredPadding(cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = blockSizeInBytes - message.length % blockSizeInBytes; + return reqd; + } + + // Remove padding when the final byte gives the number of padding bytes. + var _unpadLength = function (cipher, message, alg, padding) { + var pad = message.pop(); + if (pad == 0) { + throw new Error("Invalid zero-length padding specified for " + alg + + ". Wrong cipher specification or key used?"); + } + var maxPad = cipher._blocksize * 4; + if (pad > maxPad) { + throw new Error("Invalid padding length of " + pad + + " specified for " + alg + + ". Wrong cipher specification or key used?"); + } + for (var i = 1; i < pad; i++) { + var b = message.pop(); + if (padding != undefined && padding != b) { + throw new Error("Invalid padding byte of 0x" + b.toString(16) + + " specified for " + alg + + ". Wrong cipher specification or key used?"); + } + } + }; + + // No-operation padding, used for stream ciphers + C_pad.NoPadding = { + pad: function (cipher, message) { }, + unpad: function (cipher, message) { } + }; + + // Zero Padding. + // + // If the message is not an exact number of blocks, the final block is + // completed with 0x00 bytes. There is no unpadding. + C_pad.ZeroPadding = { + pad: function (cipher, message) { + var blockSizeInBytes = cipher._blocksize * 4; + var reqd = message.length % blockSizeInBytes; + if (reqd != 0) { + for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) { + message.push(0x00); + } + } + }, + + unpad: function (cipher, message) { + while (message[message.length - 1] == 0) { + message.pop(); + } + } + }; + + // ISO/IEC 7816-4 padding. + // + // Pads the plain text with an 0x80 byte followed by as many 0x00 + // bytes are required to complete the block. + C_pad.iso7816 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + message.push(0x80); + for (; reqd > 1; reqd--) { + message.push(0x00); + } + }, + + unpad: function (cipher, message) { + var padLength; + for (padLength = cipher._blocksize * 4; padLength > 0; padLength--) { + var b = message.pop(); + if (b == 0x80) return; + if (b != 0x00) { + throw new Error("ISO-7816 padding byte must be 0, not 0x" + b.toString(16) + ". Wrong cipher specification or key used?"); + } + } + throw new Error("ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?"); + } + }; + + // ANSI X.923 padding + // + // The final block is padded with zeros except for the last byte of the + // last block which contains the number of padding bytes. + C_pad.ansix923 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(0x00); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ANSI X.923", 0); + } + }; + + // ISO 10126 + // + // The final block is padded with random bytes except for the last + // byte of the last block which contains the number of padding bytes. + C_pad.iso10126 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 1; i < reqd; i++) { + message.push(Math.floor(Math.random() * 256)); + } + message.push(reqd); + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "ISO 10126", undefined); + } + }; + + // PKCS7 padding + // + // PKCS7 is described in RFC 5652. Padding is in whole bytes. The + // value of each added byte is the number of bytes that are added, + // i.e. N bytes, each of value N are added. + C_pad.pkcs7 = { + pad: function (cipher, message) { + var reqd = _requiredPadding(cipher, message); + for (var i = 0; i < reqd; i++) { + message.push(reqd); + } + }, + + unpad: function (cipher, message) { + _unpadLength(cipher, message, "PKCS 7", message[message.length - 1]); + } + }; + + // Create mode namespace + var C_mode = C.mode = {}; + + /** + * Mode base "class". + */ + var Mode = C_mode.Mode = function (padding) { + if (padding) { + this._padding = padding; + } + }; + + Mode.prototype = { + encrypt: function (cipher, m, iv) { + this._padding.pad(cipher, m); + this._doEncrypt(cipher, m, iv); + }, + + decrypt: function (cipher, m, iv) { + this._doDecrypt(cipher, m, iv); + this._padding.unpad(cipher, m); + }, + + // Default padding + _padding: C_pad.iso7816 + }; + + + /** + * Electronic Code Book mode. + * + * ECB applies the cipher directly against each block of the input. + * + * ECB does not require an initialization vector. + */ + var ECB = C_mode.ECB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var ECB_prototype = ECB.prototype = new Mode; + + // Concrete steps for Mode template + ECB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + cipher._encryptblock(m, offset); + } + }; + ECB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + cipher._decryptblock(c, offset); + } + }; + + // ECB never uses an IV + ECB_prototype.fixOptions = function (options) { + options.iv = []; + }; + + + /** + * Cipher block chaining + * + * The first block is XORed with the IV. Subsequent blocks are XOR with the + * previous cipher output. + */ + var CBC = C_mode.CBC = function () { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CBC_prototype = CBC.prototype = new Mode; + + // Concrete steps for Mode template + CBC_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // Encrypt each block + for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { + if (offset == 0) { + // XOR first block using IV + for (var i = 0; i < blockSizeInBytes; i++) + m[i] ^= iv[i]; + } else { + // XOR this block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) + m[offset + i] ^= m[offset + i - blockSizeInBytes]; + } + // Encrypt block + cipher._encryptblock(m, offset); + } + }; + CBC_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + + // At the start, the previously crypted block is the IV + var prevCryptedBlock = iv; + + // Decrypt each block + for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { + // Save this crypted block + var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); + // Decrypt block + cipher._decryptblock(c, offset); + // XOR decrypted block using previous crypted block + for (var i = 0; i < blockSizeInBytes; i++) { + c[offset + i] ^= prevCryptedBlock[i]; + } + prevCryptedBlock = thisCryptedBlock; + } + }; + + + /** + * Cipher feed back + * + * The cipher output is XORed with the plain text to produce the cipher output, + * which is then fed back into the cipher to produce a bit pattern to XOR the + * next block with. + * + * This is a stream cipher mode and does not require padding. + */ + var CFB = C_mode.CFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CFB_prototype = CFB.prototype = new Mode; + + // Override padding + CFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + CFB_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + m[i] ^= keystream[j]; + keystream[j] = m[i]; + } + }; + CFB_prototype._doDecrypt = function (cipher, c, iv) { + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < c.length; i++) { + + var j = i % blockSizeInBytes; + if (j == 0) cipher._encryptblock(keystream, 0); + + var b = c[i]; + c[i] ^= keystream[j]; + keystream[j] = b; + } + }; + + + /** + * Output feed back + * + * The cipher repeatedly encrypts its own output. The output is XORed with the + * plain text to produce the cipher text. + * + * This is a stream cipher mode and does not require padding. + */ + var OFB = C_mode.OFB = function () { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var OFB_prototype = OFB.prototype = new Mode; + + // Override padding + OFB_prototype._padding = C_pad.NoPadding; + + // Concrete steps for Mode template + OFB_prototype._doEncrypt = function (cipher, m, iv) { + + var blockSizeInBytes = cipher._blocksize * 4, + keystream = iv.slice(0); + + // Encrypt each byte + for (var i = 0; i < m.length; i++) { + + // Generate keystream + if (i % blockSizeInBytes == 0) + cipher._encryptblock(keystream, 0); + + // Encrypt byte + m[i] ^= keystream[i % blockSizeInBytes]; + + } + }; + OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; + + /** + * Counter + * @author Gergely Risko + * + * After every block the last 4 bytes of the IV is increased by one + * with carry and that IV is used for the next block. + * + * This is a stream cipher mode and does not require padding. + */ + var CTR = C_mode.CTR = function () { + // Call parent constructor + Mode.apply(this, arguments); + }; + + // Inherit from Mode + var CTR_prototype = CTR.prototype = new Mode; + + // Override padding + CTR_prototype._padding = C_pad.NoPadding; + + CTR_prototype._doEncrypt = function (cipher, m, iv) { + var blockSizeInBytes = cipher._blocksize * 4; + var counter = iv.slice(0); + + for (var i = 0; i < m.length; ) { + // do not lose iv + var keystream = counter.slice(0); + + // Generate keystream for next block + cipher._encryptblock(keystream, 0); + + // XOR keystream with block + for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { + m[i] ^= keystream[j]; + } + + // Increase counter + if (++(counter[blockSizeInBytes - 1]) == 256) { + counter[blockSizeInBytes - 1] = 0; + if (++(counter[blockSizeInBytes - 2]) == 256) { + counter[blockSizeInBytes - 2] = 0; + if (++(counter[blockSizeInBytes - 3]) == 256) { + counter[blockSizeInBytes - 3] = 0; + ++(counter[blockSizeInBytes - 4]); + } + } + } + } + }; + CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; + +})(Crypto); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.hmac.js b/react/src/util/crypto/gen/cryptojs.hmac.js new file mode 100755 index 0000000..f33ac76 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.hmac.js @@ -0,0 +1,43 @@ +/*! +* Crypto-JS v2.5.4 HMAC.js +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +*/ +(function () { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.HMAC = function (hasher, message, key, options) { + + // Convert to byte arrays + if (message.constructor == String) message = UTF8.stringToBytes(message); + if (key.constructor == String) key = UTF8.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize * 4) + key = hasher(key, { asBytes: true }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize * 4; i++) { + okey[i] ^= 0x5C; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true }); + + return options && options.asBytes ? hmacbytes : + options && options.asString ? Binary.bytesToString(hmacbytes) : + util.bytesToHex(hmacbytes); + + }; + +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.js b/react/src/util/crypto/gen/cryptojs.js new file mode 100755 index 0000000..b8d2b15 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.js @@ -0,0 +1,149 @@ +/*! +* Crypto-JS v2.5.4 Crypto.js +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +*/ +if (typeof Crypto == "undefined" || !Crypto.util) { + (function () { + + var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + // Global Crypto object + var Crypto = window.Crypto = {}; + + // Crypto utilities + var util = Crypto.util = { + + // Bit-wise rotate left + rotl: function (n, b) { + return (n << b) | (n >>> (32 - b)); + }, + + // Bit-wise rotate right + rotr: function (n, b) { + return (n << (32 - b)) | (n >>> b); + }, + + // Swap big-endian to little-endian and vice versa + endian: function (n) { + + // If number given, swap endian + if (n.constructor == Number) { + return util.rotl(n, 8) & 0x00FF00FF | + util.rotl(n, 24) & 0xFF00FF00; + } + + // Else, assume array and swap all items + for (var i = 0; i < n.length; i++) + n[i] = util.endian(n[i]); + return n; + + }, + + // Generate an array of any length of random bytes + randomBytes: function (n) { + for (var bytes = []; n > 0; n--) + bytes.push(Math.floor(Math.random() * 256)); + return bytes; + }, + + // Convert a byte array to big-endian 32-bit words + bytesToWords: function (bytes) { + for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) + words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32); + return words; + }, + + // Convert big-endian 32-bit words to a byte array + wordsToBytes: function (words) { + for (var bytes = [], b = 0; b < words.length * 32; b += 8) + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + return bytes; + }, + + // Convert a byte array to a hex string + bytesToHex: function (bytes) { + for (var hex = [], i = 0; i < bytes.length; i++) { + hex.push((bytes[i] >>> 4).toString(16)); + hex.push((bytes[i] & 0xF).toString(16)); + } + return hex.join(""); + }, + + // Convert a hex string to a byte array + hexToBytes: function (hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; + }, + + // Convert a byte array to a base-64 string + bytesToBase64: function (bytes) { + for (var base64 = [], i = 0; i < bytes.length; i += 3) { + var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; + for (var j = 0; j < 4; j++) { + if (i * 8 + j * 6 <= bytes.length * 8) + base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); + else base64.push("="); + } + } + + return base64.join(""); + }, + + // Convert a base-64 string to a byte array + base64ToBytes: function (base64) { + // Remove non-base-64 characters + base64 = base64.replace(/[^A-Z0-9+\/]/ig, ""); + + for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) { + if (imod4 == 0) continue; + bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | + (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); + } + + return bytes; + } + + }; + + // Crypto character encodings + var charenc = Crypto.charenc = {}; + + // UTF-8 encoding + var UTF8 = charenc.UTF8 = { + + // Convert a string to a byte array + stringToBytes: function (str) { + return Binary.stringToBytes(unescape(encodeURIComponent(str))); + }, + + // Convert a byte array to a string + bytesToString: function (bytes) { + return decodeURIComponent(escape(Binary.bytesToString(bytes))); + } + + }; + + // Binary encoding + var Binary = charenc.Binary = { + + // Convert a string to a byte array + stringToBytes: function (str) { + for (var bytes = [], i = 0; i < str.length; i++) + bytes.push(str.charCodeAt(i) & 0xFF); + return bytes; + }, + + // Convert a byte array to a string + bytesToString: function (bytes) { + for (var str = [], i = 0; i < bytes.length; i++) + str.push(String.fromCharCode(bytes[i])); + return str.join(""); + } + + }; + + })(); +} \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.pbkdf2.js b/react/src/util/crypto/gen/cryptojs.pbkdf2.js new file mode 100755 index 0000000..e5be087 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.pbkdf2.js @@ -0,0 +1,54 @@ +/*! +* Crypto-JS v2.5.4 PBKDF2.js +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +*/ +(function () { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + C.PBKDF2 = function (password, salt, keylen, options) { + + // Convert to byte arrays + if (password.constructor == String) password = UTF8.stringToBytes(password); + if (salt.constructor == String) salt = UTF8.stringToBytes(salt); + /* else, assume byte arrays already */ + + // Defaults + var hasher = options && options.hasher || C.SHA1, + iterations = options && options.iterations || 1; + + // Pseudo-random function + function PRF(password, salt) { + return C.HMAC(hasher, salt, password, { asBytes: true }); + } + + // Generate key + var derivedKeyBytes = [], + blockindex = 1; + while (derivedKeyBytes.length < keylen) { + var block = PRF(password, salt.concat(util.wordsToBytes([blockindex]))); + for (var u = block, i = 1; i < iterations; i++) { + u = PRF(password, u); + for (var j = 0; j < block.length; j++) block[j] ^= u[j]; + } + derivedKeyBytes = derivedKeyBytes.concat(block); + blockindex++; + } + + // Truncate excess bytes + derivedKeyBytes.length = keylen; + + return options && options.asBytes ? derivedKeyBytes : + options && options.asString ? Binary.bytesToString(derivedKeyBytes) : + util.bytesToHex(derivedKeyBytes); + + }; + +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.ripemd160.js b/react/src/util/crypto/gen/cryptojs.ripemd160.js new file mode 100755 index 0000000..6917536 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.ripemd160.js @@ -0,0 +1,164 @@ +/*! +* Crypto-JS v2.0.0 RIPEMD-160 +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +* +* A JavaScript implementation of the RIPEMD-160 Algorithm +* Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009. +* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet +* Distributed under the BSD License +* See http://pajhome.org.uk/crypt/md5 for details. +* Also http://www.ocf.berkeley.edu/~jjlin/jsotp/ +* Ported to Crypto-JS by Stefan Thomas. +*/ + +(function () { + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + // Convert a byte array to little-endian 32-bit words + util.bytesToLWords = function (bytes) { + + var output = Array(bytes.length >> 2); + for (var i = 0; i < output.length; i++) + output[i] = 0; + for (var i = 0; i < bytes.length * 8; i += 8) + output[i >> 5] |= (bytes[i / 8] & 0xFF) << (i % 32); + return output; + }; + + // Convert little-endian 32-bit words to a byte array + util.lWordsToBytes = function (words) { + var output = []; + for (var i = 0; i < words.length * 32; i += 8) + output.push((words[i >> 5] >>> (i % 32)) & 0xff); + return output; + }; + + // Public API + var RIPEMD160 = C.RIPEMD160 = function (message, options) { + var digestbytes = util.lWordsToBytes(RIPEMD160._rmd160(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); + }; + + // The core + RIPEMD160._rmd160 = function (message) { + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + + var x = util.bytesToLWords(message), + len = message.length * 8; + + /* append padding */ + x[len >> 5] |= 0x80 << (len % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var h0 = 0x67452301; + var h1 = 0xefcdab89; + var h2 = 0x98badcfe; + var h3 = 0x10325476; + var h4 = 0xc3d2e1f0; + + for (var i = 0; i < x.length; i += 16) { + var T; + var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4; + var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4; + for (var j = 0; j <= 79; ++j) { + T = safe_add(A1, rmd160_f(j, B1, C1, D1)); + T = safe_add(T, x[i + rmd160_r1[j]]); + T = safe_add(T, rmd160_K1(j)); + T = safe_add(bit_rol(T, rmd160_s1[j]), E1); + A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T; + T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2)); + T = safe_add(T, x[i + rmd160_r2[j]]); + T = safe_add(T, rmd160_K2(j)); + T = safe_add(bit_rol(T, rmd160_s2[j]), E2); + A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T; + } + T = safe_add(h1, safe_add(C1, D2)); + h1 = safe_add(h2, safe_add(D1, E2)); + h2 = safe_add(h3, safe_add(E1, A2)); + h3 = safe_add(h4, safe_add(A1, B2)); + h4 = safe_add(h0, safe_add(B1, C2)); + h0 = T; + } + return [h0, h1, h2, h3, h4]; + } + + function rmd160_f(j, x, y, z) { + return (0 <= j && j <= 15) ? (x ^ y ^ z) : + (16 <= j && j <= 31) ? (x & y) | (~x & z) : + (32 <= j && j <= 47) ? (x | ~y) ^ z : + (48 <= j && j <= 63) ? (x & z) | (y & ~z) : + (64 <= j && j <= 79) ? x ^ (y | ~z) : + "rmd160_f: j out of range"; + } + function rmd160_K1(j) { + return (0 <= j && j <= 15) ? 0x00000000 : + (16 <= j && j <= 31) ? 0x5a827999 : + (32 <= j && j <= 47) ? 0x6ed9eba1 : + (48 <= j && j <= 63) ? 0x8f1bbcdc : + (64 <= j && j <= 79) ? 0xa953fd4e : + "rmd160_K1: j out of range"; + } + function rmd160_K2(j) { + return (0 <= j && j <= 15) ? 0x50a28be6 : + (16 <= j && j <= 31) ? 0x5c4dd124 : + (32 <= j && j <= 47) ? 0x6d703ef3 : + (48 <= j && j <= 63) ? 0x7a6d76e9 : + (64 <= j && j <= 79) ? 0x00000000 : + "rmd160_K2: j out of range"; + } + var rmd160_r1 = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 + ]; + var rmd160_r2 = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 + ]; + var rmd160_s1 = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 + ]; + var rmd160_s2 = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 + ]; + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function safe_add(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function bit_rol(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); + } +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/cryptojs.sha256.js b/react/src/util/crypto/gen/cryptojs.sha256.js new file mode 100755 index 0000000..8209973 --- /dev/null +++ b/react/src/util/crypto/gen/cryptojs.sha256.js @@ -0,0 +1,135 @@ +/*! +* Crypto-JS v2.5.4 SHA256.js +* http://code.google.com/p/crypto-js/ +* Copyright (c) 2009-2013, Jeff Mott. All rights reserved. +* http://code.google.com/p/crypto-js/wiki/License +*/ +(function () { + + // Shortcuts + var C = Crypto, + util = C.util, + charenc = C.charenc, + UTF8 = charenc.UTF8, + Binary = charenc.Binary; + + // Constants + var K = [0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2]; + + // Public API + var SHA256 = C.SHA256 = function (message, options) { + var digestbytes = util.wordsToBytes(SHA256._sha256(message)); + return options && options.asBytes ? digestbytes : + options && options.asString ? Binary.bytesToString(digestbytes) : + util.bytesToHex(digestbytes); + }; + + // The core + SHA256._sha256 = function (message) { + + // Convert to byte array + if (message.constructor == String) message = UTF8.stringToBytes(message); + /* else, assume byte array already */ + + var m = util.bytesToWords(message), + l = message.length * 8, + H = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19], + w = [], + a, b, c, d, e, f, g, h, i, j, + t1, t2; + + // Padding + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for (var i = 0; i < m.length; i += 16) { + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + + for (var j = 0; j < 64; j++) { + + if (j < 16) w[j] = m[j + i]; + else { + + var gamma0x = w[j - 15], + gamma1x = w[j - 2], + gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ + ((gamma0x << 14) | (gamma0x >>> 18)) ^ + (gamma0x >>> 3), + gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ + ((gamma1x << 13) | (gamma1x >>> 19)) ^ + (gamma1x >>> 10); + + w[j] = gamma0 + (w[j - 7] >>> 0) + + gamma1 + (w[j - 16] >>> 0); + + } + + var ch = e & f ^ ~e & g, + maj = a & b ^ a & c ^ b & c, + sigma0 = ((a << 30) | (a >>> 2)) ^ + ((a << 19) | (a >>> 13)) ^ + ((a << 10) | (a >>> 22)), + sigma1 = ((e << 26) | (e >>> 6)) ^ + ((e << 21) | (e >>> 11)) ^ + ((e << 7) | (e >>> 25)); + + + t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0); + t2 = sigma0 + maj; + + h = g; + g = f; + f = e; + e = (d + t1) >>> 0; + d = c; + c = b; + b = a; + a = (t1 + t2) >>> 0; + + } + + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; + + } + + return H; + + }; + + // Package private blocksize + SHA256._blocksize = 16; + + SHA256._digestsize = 32; + +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/ellipticcurve.js b/react/src/util/crypto/gen/ellipticcurve.js new file mode 100755 index 0000000..d41fee6 --- /dev/null +++ b/react/src/util/crypto/gen/ellipticcurve.js @@ -0,0 +1,669 @@ +//https://raw.github.com/bitcoinjs/bitcoinjs-lib/faa10f0f6a1fff0b9a99fffb9bc30cee33b17212/src/ecdsa.js +/*! +* Basic Javascript Elliptic Curve implementation +* Ported loosely from BouncyCastle's Java EC code +* Only Fp curves implemented for now +* +* Copyright Tom Wu, bitaddress.org BSD License. +* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE +*/ +(function () { + + // Constructor function of Global EllipticCurve object + var ec = window.EllipticCurve = function () { }; + + + // ---------------- + // ECFieldElementFp constructor + // q instanceof BigInteger + // x instanceof BigInteger + ec.FieldElementFp = function (q, x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; + }; + + ec.FieldElementFp.prototype.equals = function (other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); + }; + + ec.FieldElementFp.prototype.toBigInteger = function () { + return this.x; + }; + + ec.FieldElementFp.prototype.negate = function () { + return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q)); + }; + + ec.FieldElementFp.prototype.add = function (b) { + return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.subtract = function (b) { + return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.multiply = function (b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); + }; + + ec.FieldElementFp.prototype.square = function () { + return new ec.FieldElementFp(this.q, this.x.square().mod(this.q)); + }; + + ec.FieldElementFp.prototype.divide = function (b) { + return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); + }; + + ec.FieldElementFp.prototype.getByteLength = function () { + return Math.floor((this.toBigInteger().bitLength() + 7) / 8); + }; + + // D.1.4 91 + /** + * return a sqrt root - the routine verifies that the calculation + * returns the right value - if none exists it returns null. + * + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.prototype.sqrt = function () { + if (!this.q.testBit(0)) throw new Error("even value of q"); + + // p mod 4 == 3 + if (this.q.testBit(1)) { + // z = g^(u+1) + p, p = 4u + 3 + var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q)); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null; + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + var Q = this.x; + var fourQ = Q.shiftLeft(2).mod(this.q); + var U, V; + + do { + var rand = new SecureRandom(); + var P; + do { + P = new BigInteger(this.q.bitLength(), rand); + } + while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); + + var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k); + + U = result[0]; + V = result[1]; + if (V.multiply(V).mod(this.q).equals(fourQ)) { + // Integer division by 2, mod q + if (V.testBit(0)) { + V = V.add(this.q); + } + V = V.shiftRight(1); + return new ec.FieldElementFp(this.q, V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; + }; + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + */ + ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) { + // TODO Research and apply "common-multiplicand multiplication here" + + var n = k.bitLength(); + var s = k.getLowestSetBit(); + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) { + Ql = Ql.multiply(Qh).mod(p); + if (k.testBit(j)) { + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vh).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p); + } + else { + Qh = Ql; + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + } + } + + Ql = Ql.multiply(Qh).mod(p); + Qh = Ql.multiply(Q).mod(p); + Uh = Uh.multiply(Vl).subtract(Ql).mod(p); + Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p); + Ql = Ql.multiply(Qh).mod(p); + + for (var j = 1; j <= s; ++j) { + Uh = Uh.multiply(Vl).mod(p); + Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p); + Ql = Ql.multiply(Ql).mod(p); + } + + return [Uh, Vl]; + }; + + // ---------------- + // ECPointFp constructor + ec.PointFp = function (curve, x, y, z, compressed) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if (z == null) { + this.z = BigInteger.ONE; + } + else { + this.z = z; + } + this.zinv = null; + // compression flag + this.compressed = !!compressed; + }; + + ec.PointFp.prototype.getX = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.getY = function () { + if (this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); + }; + + ec.PointFp.prototype.equals = function (other) { + if (other == this) return true; + if (this.isInfinity()) return other.isInfinity(); + if (other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); + if (!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); + return v.equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.isInfinity = function () { + if ((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); + }; + + ec.PointFp.prototype.negate = function () { + return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z); + }; + + ec.PointFp.prototype.add = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); + + + if (BigInteger.ZERO.equals(v)) { + if (BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); + }; + + ec.PointFp.prototype.twice = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if (!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); + }; + + // Simple NAF (Non-Adjacent Form) multiplication algorithm + // TODO: modularize the multiplication algorithm + ec.PointFp.prototype.multiply = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; + }; + + // Compute this*j + x*k (simultaneous multiplication) + ec.PointFp.prototype.multiplyTwo = function (j, x, k) { + var i; + if (j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while (i >= 0) { + R = R.twice(); + if (j.testBit(i)) { + if (k.testBit(i)) { + R = R.add(both); + } + else { + R = R.add(this); + } + } + else { + if (k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; + }; + + // patched by bitaddress.org and Casascius for use with Bitcoin.ECKey + // patched by coretechs to support compressed public keys + ec.PointFp.prototype.getEncoded = function (compressed) { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. + var enc = ec.integerToBytes(x, len); + + // when compressed prepend byte depending if y point is even or odd + if (compressed) { + if (y.isEven()) { + enc.unshift(0x02); + } + else { + enc.unshift(0x03); + } + } + else { + enc.unshift(0x04); + enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point + } + return enc; + }; + + ec.PointFp.decodeFrom = function (curve, enc) { + var type = enc[0]; + var dataLen = enc.length - 1; + + // Extract x and y as byte arrays + var xBa = enc.slice(1, 1 + dataLen / 2); + var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen); + + // Prepend zero byte to prevent interpretation as negative integer + xBa.unshift(0); + yBa.unshift(0); + + // Convert to BigIntegers + var x = new BigInteger(xBa); + var y = new BigInteger(yBa); + + // Return point + return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); + }; + + ec.PointFp.prototype.add2D = function (b) { + if (this.isInfinity()) return b; + if (b.isInfinity()) return this; + + if (this.x.equals(b.x)) { + if (this.y.equals(b.y)) { + // this = b, i.e. this must be doubled + return this.twice(); + } + // this = -b, i.e. the result is the point at infinity + return this.curve.getInfinity(); + } + + var x_x = b.x.subtract(this.x); + var y_y = b.y.subtract(this.y); + var gamma = y_y.divide(x_x); + + var x3 = gamma.square().subtract(this.x).subtract(b.x); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.twice2D = function () { + if (this.isInfinity()) return this; + if (this.y.toBigInteger().signum() == 0) { + // if y1 == 0, then (x1, y1) == (x1, -y1) + // and hence this = -this and thus 2(x1, y1) == infinity + return this.curve.getInfinity(); + } + + var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2)); + var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3)); + var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO)); + + var x3 = gamma.square().subtract(this.x.multiply(TWO)); + var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y); + + return new ec.PointFp(this.curve, x3, y3); + }; + + ec.PointFp.prototype.multiply2D = function (k) { + if (this.isInfinity()) return this; + if (k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for (i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add2D(hBit ? this : neg); + } + } + + return R; + }; + + ec.PointFp.prototype.isOnCurve = function () { + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + var a = this.curve.getA().toBigInteger(); + var b = this.curve.getB().toBigInteger(); + var n = this.curve.getQ(); + var lhs = y.multiply(y).mod(n); + var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n); + return lhs.equals(rhs); + }; + + ec.PointFp.prototype.toString = function () { + return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + ')'; + }; + + /** + * Validate an elliptic curve point. + * + * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive + */ + ec.PointFp.prototype.validate = function () { + var n = this.curve.getQ(); + + // Check Q != O + if (this.isInfinity()) { + throw new Error("Point is at infinity."); + } + + // Check coordinate bounds + var x = this.getX().toBigInteger(); + var y = this.getY().toBigInteger(); + if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('x coordinate out of bounds'); + } + if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) { + throw new Error('y coordinate out of bounds'); + } + + // Check y^2 = x^3 + ax + b (mod n) + if (!this.isOnCurve()) { + throw new Error("Point is not on the curve."); + } + + // Check nQ = 0 (Q is a scalar multiple of G) + if (this.multiply(n).isInfinity()) { + // TODO: This check doesn't work - fix. + throw new Error("Point is not a scalar multiple of G."); + } + + return true; + }; + + + + + // ---------------- + // ECCurveFp constructor + ec.CurveFp = function (q, a, b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ec.PointFp(this, null, null); + this.reducer = new Barrett(this.q); + } + + ec.CurveFp.prototype.getQ = function () { + return this.q; + }; + + ec.CurveFp.prototype.getA = function () { + return this.a; + }; + + ec.CurveFp.prototype.getB = function () { + return this.b; + }; + + ec.CurveFp.prototype.equals = function (other) { + if (other == this) return true; + return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); + }; + + ec.CurveFp.prototype.getInfinity = function () { + return this.infinity; + }; + + ec.CurveFp.prototype.fromBigInteger = function (x) { + return new ec.FieldElementFp(this.q, x); + }; + + ec.CurveFp.prototype.reduce = function (x) { + this.reducer.reduce(x); + }; + + // for now, work with hex strings because they're easier in JS + // compressed support added by bitaddress.org + ec.CurveFp.prototype.decodePointHex = function (s) { + var firstByte = parseInt(s.substr(0, 2), 16); + switch (firstByte) { // first byte + case 0: + return this.infinity; + case 2: // compressed + case 3: // compressed + var yTilde = firstByte & 1; + var xHex = s.substr(2, s.length - 2); + var X1 = new BigInteger(xHex, 16); + return this.decompressPoint(yTilde, X1); + case 4: // uncompressed + case 6: // hybrid + case 7: // hybrid + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len + 2, len); + + return new ec.PointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } + }; + + ec.CurveFp.prototype.encodePointHex = function (p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; + }; + + /* + * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + * Ported to JavaScript by bitaddress.org + * + * Number yTilde + * BigInteger X1 + */ + ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) { + var x = this.fromBigInteger(X1); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + // if we can't find a sqrt we haven't got a point on the curve - run! + if (beta == null) throw new Error("Invalid point compression"); + var betaValue = beta.toBigInteger(); + var bit0 = betaValue.testBit(0) ? 1 : 0; + if (bit0 != yTilde) { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ec.PointFp(this, x, beta, null, true); + }; + + + ec.fromHex = function (s) { return new BigInteger(s, 16); }; + + ec.integerToBytes = function (i, len) { + var bytes = i.toByteArrayUnsigned(); + if (len < bytes.length) { + bytes = bytes.slice(bytes.length - len); + } else while (len > bytes.length) { + bytes.unshift(0); + } + return bytes; + }; + + + // Named EC curves + // ---------------- + // X9ECParameters constructor + ec.X9Parameters = function (curve, g, n, h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + } + ec.X9Parameters.prototype.getCurve = function () { return this.curve; }; + ec.X9Parameters.prototype.getG = function () { return this.g; }; + ec.X9Parameters.prototype.getN = function () { return this.n; }; + ec.X9Parameters.prototype.getH = function () { return this.h; }; + + // secp256k1 is the Curve used by Bitcoin + ec.secNamedCurves = { + // used by Bitcoin + "secp256k1": function () { + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); + var a = BigInteger.ZERO; + var b = ec.fromHex("7"); + var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); + var h = BigInteger.ONE; + var curve = new ec.CurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" + + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"); + return new ec.X9Parameters(curve, G, n, h); + } + }; + + // secp256k1 called by Bitcoin's ECKEY + ec.getSECCurveByName = function (name) { + if (ec.secNamedCurves[name] == undefined) return null; + return ec.secNamedCurves[name](); + } +})(); \ No newline at end of file diff --git a/react/src/util/crypto/gen/securerandom.js b/react/src/util/crypto/gen/securerandom.js new file mode 100755 index 0000000..51b8349 --- /dev/null +++ b/react/src/util/crypto/gen/securerandom.js @@ -0,0 +1,187 @@ +/*! +* Random number generator with ArcFour PRNG +* +* NOTE: For best results, put code like +* +* in your main HTML document. +* +* Copyright Tom Wu, bitaddress.org BSD License. +* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE +*/ +(function () { + + // Constructor function of Global SecureRandom object + var sr = window.SecureRandom = function () { }; + + // Properties + sr.state; + sr.pool; + sr.pptr; + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + sr.poolSize = 256; + + // --- object methods --- + + // public method + // ba: byte array + sr.prototype.nextBytes = function (ba) { + var i; + if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) { + try { + var rvBytes = new Uint8Array(ba.length); + window.crypto.getRandomValues(rvBytes); + for (i = 0; i < ba.length; ++i) + ba[i] = sr.getByte() ^ rvBytes[i]; + return; + } catch (e) { + alert(e); + } + } + for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte(); + }; + + + // --- static methods --- + + // Mix in the current time (w/milliseconds) into the pool + // NOTE: this method should be called from body click/keypress event handlers to increase entropy + sr.seedTime = function () { + sr.seedInt(new Date().getTime()); + } + + sr.getByte = function () { + /*if(!ninja.seeder.isDone()) { + alert("Premature initialisation of the random generator. Something is really wrong, do not generate wallets."); + return NaN; + }*/ + + if (sr.state == null) { + sr.seedTime(); + sr.state = sr.ArcFour(); // Plug in your RNG constructor here + sr.state.init(sr.pool); + sr.pptr = 0; + } + // TODO: allow reseeding after first request + return sr.state.next(); + } + + // Mix in a 32-bit integer into the pool + sr.seedInt = function (x) { + sr.seedInt8(x); + sr.seedInt8((x >> 8)); + sr.seedInt8((x >> 16)); + sr.seedInt8((x >> 24)); + } + + // Mix in a 16-bit integer into the pool + sr.seedInt16 = function (x) { + sr.seedInt8(x); + sr.seedInt8((x >> 8)); + } + + // Mix in a 8-bit integer into the pool + sr.seedInt8 = function (x) { + sr.pool[sr.pptr++] ^= x & 255; + if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize; + } + + // Arcfour is a PRNG + sr.ArcFour = function () { + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for (i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + return new Arcfour(); + }; + + + // Initialize the pool with junk if needed. + if (sr.pool == null) { + sr.pool = new Array(); + sr.pptr = 0; + var t; + if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) { + try { + // Use webcrypto if available + var ua = new Uint8Array(sr.poolSize); + window.crypto.getRandomValues(ua); + for (t = 0; t < sr.poolSize; ++t) + sr.pool[sr.pptr++] = ua[t]; + } catch (e) { alert(e); } + } + while (sr.pptr < sr.poolSize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + sr.pool[sr.pptr++] = t >>> 8; + sr.pool[sr.pptr++] = t & 255; + } + sr.pptr = Math.floor(sr.poolSize * Math.random()); + sr.seedTime(); + // entropy + var entropyStr = ""; + // screen size and color depth: ~4.8 to ~5.4 bits + entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth); + entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth); + // time zone offset: ~4 bits + var dateObj = new Date(); + var timeZoneOffset = dateObj.getTimezoneOffset(); + entropyStr += timeZoneOffset; + // user agent: ~8.3 to ~11.6 bits + entropyStr += navigator.userAgent; + // browser plugin details: ~16.2 to ~21.8 bits + var pluginsStr = ""; + for (var i = 0; i < navigator.plugins.length; i++) { + pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", "; + } + var mimeTypesStr = ""; + for (var i = 0; i < navigator.mimeTypes.length; i++) { + mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", "; + } + entropyStr += pluginsStr + mimeTypesStr; + // cookies and storage: 1 bit + entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage); + // language: ~7 bit + entropyStr += navigator.language; + // history: ~2 bit + entropyStr += window.history.length; + // location + entropyStr += window.location; + + var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true }); + for (var i = 0 ; i < entropyBytes.length ; i++) { + sr.seedInt8(entropyBytes[i]); + } + } +})(); \ No newline at end of file From 9c602dab7cd44be9a9f59be6165d6d735744102d Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 12 Aug 2017 20:32:41 +0300 Subject: [PATCH 54/58] zcash params check --- react/change.log | 3 +++ .../components/dashboard/jumblr/jumblr.render.js | 1 - react/src/components/main/main.js | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/react/change.log b/react/change.log index 65eee02..239bf47 100644 --- a/react/change.log +++ b/react/change.log @@ -16,6 +16,9 @@ UI: - qr code generator / scan - basilisk send form reset fix - added native wallet info button +- added coqui assetchain +- jumblr +- zcashparams folder check v0.2.0.21a-beta -------------- diff --git a/react/src/components/dashboard/jumblr/jumblr.render.js b/react/src/components/dashboard/jumblr/jumblr.render.js index fab7b1c..0e8b25e 100644 --- a/react/src/components/dashboard/jumblr/jumblr.render.js +++ b/react/src/components/dashboard/jumblr/jumblr.render.js @@ -9,7 +9,6 @@ export const JumblrRenderSecretAddressList = function(type) { const _jumblrAddressList = type === 'gen' ? this.state.jumblrSecretAddress : this.state.jumblrSecretAddressImport; let _items = []; - console.warn('_jumblrAddressList', type); if (_jumblrAddressList && _jumblrAddressList.length) { for (let i = 0; i < _jumblrAddressList.length; i++) { diff --git a/react/src/components/main/main.js b/react/src/components/main/main.js index 88f66c3..6394888 100644 --- a/react/src/components/main/main.js +++ b/react/src/components/main/main.js @@ -5,7 +5,8 @@ import Store from '../../store'; import { Config, getDexCoins, - iguanaActiveHandle + iguanaActiveHandle, + triggerToaster } from '../../actions/actionCreators'; const IGUANA_ACTIVE_HANDLE_TIMEOUT = 30000; @@ -24,15 +25,28 @@ class Main extends React.Component { componentDidMount() { let appVersion; + let zcashParamsExist; try { appVersion = window.require('electron').remote.getCurrentWindow().appBasicInfo; + zcashParamsExist = window.require('electron').remote.getCurrentWindow().zcashParamsExist; } catch (e) {} if (appVersion) { document.title = `${appVersion.name} (v${appVersion.version.replace('version=', '')}-beta)`; } + if (!zcashParamsExist) { + Store.dispatch( + triggerToaster( + 'Zcash params are missing', + 'Komodo', + 'error', + false + ) + ); + } + Store.dispatch(iguanaActiveHandle()); const _iguanaActiveHandle = setInterval(function() { Store.dispatch(iguanaActiveHandle()); From 7b138a94891d444ae63edfd9bd32d9914a0e9c5b Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 14 Aug 2017 17:29:56 +0300 Subject: [PATCH 55/58] claim interest modal --- react/src/actions/actionCreators.js | 9 ++ react/src/actions/actions/interest.js | 86 +++++++++++ react/src/actions/actions/log.js | 1 - react/src/actions/actions/nativeSend.js | 43 +++++- react/src/actions/actions/nativeSyncInfo.js | 2 +- react/src/actions/storeType.js | 3 +- .../claimInterestModal/claimInterestModal.js | 118 +++++++++++++++ .../claimInterestModal.render.js | 140 ++++++++++++++++++ .../src/components/dashboard/navbar/navbar.js | 6 + .../dashboard/navbar/navbar.render.js | 2 +- .../walletsNativeInfo/walletsNativeInfo.js | 7 + .../walletsNativeInfo.render.js | 10 ++ react/src/components/overrides.scss | 44 ++++++ react/src/reducers/dashboard.js | 13 +- 14 files changed, 476 insertions(+), 8 deletions(-) create mode 100644 react/src/actions/actions/interest.js create mode 100755 react/src/components/dashboard/claimInterestModal/claimInterestModal.js create mode 100644 react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index 68e99e4..5919f83 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -27,6 +27,7 @@ import { DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY, DISPLAY_LOGIN_SETTINGS_MODAL, DISPLAY_COIND_DOWN_MODAL, + DISPLAY_CLAIM_INTEREST_MODAL, START_INTERVAL, STOP_INTERVAL } from './storeType'; @@ -69,6 +70,7 @@ export * from './actions/iguanaHelpers'; export * from './actions/cli'; export * from './actions/update'; export * from './actions/jumblr'; +export * from './actions/interest'; export function changeActiveAddress(address) { return { @@ -367,4 +369,11 @@ export function toggleLoginSettingsModal(display) { type: DISPLAY_LOGIN_SETTINGS_MODAL, displayLoginSettingsModal: display, } +} + +export function toggleClaimInterestModal(display) { + return { + type: DISPLAY_CLAIM_INTEREST_MODAL, + displayClaimInterestModal: display, + } } \ No newline at end of file diff --git a/react/src/actions/actions/interest.js b/react/src/actions/actions/interest.js new file mode 100644 index 0000000..1dd95c6 --- /dev/null +++ b/react/src/actions/actions/interest.js @@ -0,0 +1,86 @@ +import { + triggerToaster +} from '../actionCreators'; +import { + logGuiHttp, + guiLogState +} from './log'; +import Config from '../../config'; + +export function getListUnspent(coin) { + return new Promise((resolve, reject) => { + const payload = { + mode: null, + chain: coin, + cmd: 'listunspent', + }; + + 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); + dispatch( + triggerToaster( + 'getListUnspent', + 'Error', + 'error' + ) + ); + }) + .then(response => response.json()) + .then(json => { + resolve(json.result ? json.result : json); + }) + }); +} + +export function getRawTransaction(coin, txid) { + return new Promise((resolve, reject) => { + const payload = { + mode: null, + chain: coin, + cmd: 'getrawtransaction', + params: [ + txid, + 1 + ], + }; + + 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); + dispatch( + triggerToaster( + 'getTransaction', + '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/log.js b/react/src/actions/actions/log.js index ca42d5b..c53f402 100644 --- a/react/src/actions/actions/log.js +++ b/react/src/actions/actions/log.js @@ -41,7 +41,6 @@ export function getAgamaLog(type) { ); }) .then(response => response.json()) - .then() } } diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index 0f788c8..e6cbfbc 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -195,7 +195,7 @@ export function getKMDOPID(opid, coin) { passthruAgent = getPassthruAgent(coin), tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`; - if (passthruAgent == 'iguana') { + if (passthruAgent === 'iguana') { payload = { 'userpass': tmpIguanaRPCAuth, 'agent': passthruAgent, @@ -284,4 +284,45 @@ export function getKMDOPID(opid, coin) { }) }) } +} + +export function sendFromPromise(coin, address, amount) { + return new Promise((resolve, reject) => { + const payload = { + mode: null, + chain: coin, + cmd: 'sendfrom', + params: [ + address, + amount + ] + }; + + 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); + dispatch( + triggerToaster( + 'sendFrom', + '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/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index 196ef53..b75b161 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -13,7 +13,7 @@ import Config from '../../config'; export function getSyncInfoNativeKMD(skipDebug, json) { const coin = 'KMD'; - + // https://www.kmd.host/ return dispatch => { const _timestamp = Date.now(); if (Config.debug) { diff --git a/react/src/actions/storeType.js b/react/src/actions/storeType.js index 23deb33..1e4c8af 100644 --- a/react/src/actions/storeType.js +++ b/react/src/actions/storeType.js @@ -45,4 +45,5 @@ export const LOG_GUI_HTTP = 'LOG_GUI_HTTP'; export const CLI = 'CLI'; export const LOGOUT = 'LOGOUT'; export const DISPLAY_COIND_DOWN_MODAL = 'DISPLAY_COIND_DOWN_MODAL'; -export const DISPLAY_LOGIN_SETTINGS_MODAL = 'DISPLAY_LOGIN_SETTINGS_MODAL'; \ No newline at end of file +export const DISPLAY_LOGIN_SETTINGS_MODAL = 'DISPLAY_LOGIN_SETTINGS_MODAL'; +export const DISPLAY_CLAIM_INTEREST_MODAL = 'DISPLAY_CLAIM_INTEREST_MODAL'; \ No newline at end of file diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js new file mode 100755 index 0000000..95b70bb --- /dev/null +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js @@ -0,0 +1,118 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Store from '../../../store'; +import { + toggleClaimInterestModal, + getListUnspent, + getRawTransaction, + copyString, + sendFromPromise +} from '../../../actions/actionCreators'; +import { translate } from '../../../translate/translate'; +import { + ClaimInterestModalRender, + _ClaimInterestTableRender +} from './claimInterestModal.render'; + +class ClaimInterestModal extends React.Component { + constructor(props) { + super(props); + this.state = { + open: false, + isLoading: true, + transactionsList: [], + showZeroInterest: true, + }; + this.claimInterestTableRender = this.claimInterestTableRender.bind(this); + this.toggleZeroInterest = this.toggleZeroInterest.bind(this); + this.loadListUnspent = this.loadListUnspent.bind(this); + this.checkTransactionsListLength = this.checkTransactionsListLength.bind(this); + } + + componentWillMount() { + this.loadListUnspent(); + } + + loadListUnspent() { + let _transactionsList = []; + + getListUnspent('KMD') + .then((json) => { + if (json && + json.length) { + for (let i = 0; i < json.length; i++) { + getRawTransaction('KMD', json[i].txid) + .then((_json) => { + _transactionsList.push({ + address: json[i].address, + locktime: _json.locktime, + amount: json[i].amount, + interest: json[i].interest, + txid: json[i].txid, + }); + + if (i === json.length - 1) { + this.setState({ + transactionsList: _transactionsList, + isLoading: false, + }); + } + }); + } + } + }); + } + + claimInterest(address, amount) { + console.warn('claim interest', `${address} ${amount}`); + /*sendFromPromise(address, amount) + .then((json) => { + console.warn(json); + });*/ + } + + checkTransactionsListLength() { + if (this.state.transactionsList && this.state.transactionsList.length) { + return true; + } else if (!this.state.transactionsList || !this.state.transactionsList.length) { + return false; + } + } + + toggleZeroInterest() { + this.setState({ + showZeroInterest: !this.state.showZeroInterest, + }); + } + + copyTxId(txid) { + Store.dispatch(copyString(txid, 'Transaction ID copied')); + } + + claimInterestTableRender() { + return _ClaimInterestTableRender.call(this); + } + + componentWillReceiveProps(props) { + if (props.Dashboard.displayClaimInterestModal !== this.state.open) { + this.setState({ + open: props.Dashboard.displayClaimInterestModal, + }); + } + + if (!this.state.open && + props.Dashboard.displayClaimInterestModal) { + this.loadListUnspent(); + } + } + + closeModal() { + Store.dispatch(toggleClaimInterestModal(false)); + } + + render() { + return ClaimInterestModalRender.call(this); + } +} + +export default ClaimInterestModal; \ No newline at end of file diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js new file mode 100644 index 0000000..8872fc2 --- /dev/null +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js @@ -0,0 +1,140 @@ +import React from 'react'; +import { translate } from '../../../translate/translate'; + +const MIN_INTEREST_THRESHOLD = 0.001; + +export const _ClaimInterestTableRender = function() { + const _transactionsList = this.state.transactionsList; + let _items = []; + + for (let i = 0; i < _transactionsList.length; i++) { + if ((_transactionsList[i].interest === 0 && this.state.showZeroInterest) || (_transactionsList[i].amount > 0 && _transactionsList[i].interest > 0)) { + _items.push( + + + + + { _transactionsList[i].address } + 10 ? 'green bold' : '' }>{ _transactionsList[i].amount } + { _transactionsList[i].interest } + + { _transactionsList[i].locktime && + + } + { !_transactionsList[i].locktime && + + } + + + + + + ); + } + } + + return ( + +
      + Requirements to accure interest: locktime field is set and amount is greater than 10 KMD +
      +
      + +
      + Show zero interest +
      +
      +
      + + + + + + + + + + + + + { _items } + + + + + + + + + + + +
      AddressAmountInterestLocktime
      AddressAmountInterestLocktime
      +
      +
      + ); +}; + + //{ this.renderAddressList('public') } + //{ this.isNativeMode() && this.renderAddressList('private') } + + +export const ClaimInterestModalRender = function() { + return ( + +
      +
      +
      +
      + +

      Claim interest

      +
      +
      + +
      +
      + { this.state.isLoading && + Loading interest data... + } + { !this.state.isLoading && this.checkTransactionsListLength() && +
      { this.claimInterestTableRender() }
      + } + { !this.state.isLoading && !this.checkTransactionsListLength() && +
      No data
      + } +
      +
      +
      +
      +
      +
      +
      +
      + ); +}; \ No newline at end of file diff --git a/react/src/components/dashboard/navbar/navbar.js b/react/src/components/dashboard/navbar/navbar.js index 6480b97..dfacb44 100755 --- a/react/src/components/dashboard/navbar/navbar.js +++ b/react/src/components/dashboard/navbar/navbar.js @@ -10,6 +10,7 @@ import { } from '../../../actions/actionCreators'; import Store from '../../../store'; import Config from '../../../config'; +import { checkAC } from '../../addcoin/payload'; import NavbarRender from './navbar.render'; @@ -23,6 +24,7 @@ class Navbar extends React.Component { this.openDropMenu = this.openDropMenu.bind(this); this.logout = this.logout.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); + this._checkAC = this._checkAC.bind(this); } componentWillMount() { @@ -67,6 +69,10 @@ class Navbar extends React.Component { Store.dispatch(dashboardChangeSection(sectionName)); } + _checkAC() { + return checkAC(this.props.ActiveCoin.coin); + } + logout() { Store.dispatch( stopInterval( diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js index 48816d0..4449f5f 100644 --- a/react/src/components/dashboard/navbar/navbar.render.js +++ b/react/src/components/dashboard/navbar/navbar.render.js @@ -57,7 +57,7 @@ const NavbarRender = function() { BarterDEX - { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && + { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && (this._checkAC() || this.props.ActiveCoin.coin === 'KMD') &&
    1. this.dashboardChangeSection('jumblr') }> Jumblr diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js index 6e025e1..4630f4e 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js +++ b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js @@ -1,9 +1,16 @@ import React from 'react'; +import { toggleClaimInterestModal } from '../../../actions/actionCreators'; +import Store from '../../../store'; import WalletsNativeInfoRender from './walletsNativeInfo.render'; class WalletsNativeInfo extends React.Component { constructor(props) { super(props); + this.openClaimInterestModal = this.openClaimInterestModal.bind(this); + } + + openClaimInterestModal() { + Store.dispatch(toggleClaimInterestModal(true)); } render() { diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js index 07bd784..19acf59 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js +++ b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js @@ -1,5 +1,6 @@ import React from 'react'; import { translate } from '../../../translate/translate'; +import ClaimInterestModal from '../claimInterestModal/claimInterestModal'; const WalletsNativeInfoRender = function() { return ( @@ -40,6 +41,15 @@ const WalletsNativeInfoRender = function() {
    + { this.props.ActiveCoin.coin === 'KMD' && +
    + + +
    + }
    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index c675967..ed599ec 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -836,4 +836,48 @@ select{ padding: 0; } } +} + +.modal-claim-interest { + .modal-dialog { + width: 70%; + + .table > tbody > tr > td, + .table > tbody > tr > th, + .table > tfoot > tr > td, + .table > tfoot > tr > th, + .table > thead > tr > td, + .table > thead > tr > th { + padding: 8px 30px 8px 0; + } + + .table-scroll { + height: 366px; + overflow-y: auto; + overflow-x: hidden; + width: 100%; + } + .bold { + font-weight: bold; + } + .green { + color: #66bb6a; + } + .red { + color: #f96868; + } + .locktime { + i { + font-size: 20px; + line-height: 1.1; + } + } + + .refresh-icon { + position: absolute; + right: 20px; + font-size: 20px; + z-index: 100; + } + } } \ No newline at end of file diff --git a/react/src/reducers/dashboard.js b/react/src/reducers/dashboard.js index 98df82e..54e2e63 100644 --- a/react/src/reducers/dashboard.js +++ b/react/src/reducers/dashboard.js @@ -9,14 +9,15 @@ import { VIEW_CACHE_DATA, LOG_GUI_HTTP, TOGGLE_NOTIFICATIONS_MODAL, - DISPLAY_COIND_DOWN_MODAL + DISPLAY_COIND_DOWN_MODAL, + DISPLAY_CLAIM_INTEREST_MODAL } from '../actions/storeType'; const HTTP_STACK_MAX_ENTRIES = 150; // limit stack mem length to N records per type const trimHTTPLogs = (logObject) => { const logObjectArray = Object.keys(logObject); - + if (logObjectArray.length - HTTP_STACK_MAX_ENTRIES === 1) { delete logObject[logObjectArray.shift()]; } @@ -38,6 +39,7 @@ export function Dashboard(state = { }, guiLog: {}, displayCoindDownModal: false, + displayClaimInterestModal: false, }, action) { switch (action.type) { case DASHBOARD_SECTION_CHANGE: @@ -95,7 +97,7 @@ export function Dashboard(state = { const logItem = { [actionTS]: action.log }; newLogState = trimHTTPLogs(Object.assign({}, logState, logItem)); } - + return Object.assign({}, state, { guiLog: newLogState, }); @@ -104,6 +106,11 @@ export function Dashboard(state = { displayCoindDownModal: action.displayCoindDownModal, }); break; + case DISPLAY_CLAIM_INTEREST_MODAL: + return Object.assign({}, state, { + displayClaimInterestModal: action.displayClaimInterestModal, + }); + break; default: return state; } From 8aa3164b23f36f1221e8fb86d0439d6250586135 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 14 Aug 2017 23:34:13 +0300 Subject: [PATCH 56/58] send whole balance to yourself --- react/src/actions/actions/nativeSend.js | 13 +++++--- .../claimInterestModal/claimInterestModal.js | 32 +++++++++++++++---- .../claimInterestModal.render.js | 22 ++++--------- .../src/components/dashboard/jumblr/jumblr.js | 8 ++--- react/src/components/overrides.scss | 5 +++ 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index e6cbfbc..fc3e3e2 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -286,15 +286,18 @@ export function getKMDOPID(opid, coin) { } } -export function sendFromPromise(coin, address, amount) { +export function sendToAddressPromise(coin, address, amount) { return new Promise((resolve, reject) => { const payload = { mode: null, chain: coin, - cmd: 'sendfrom', + cmd: 'sendtoaddress', params: [ address, - amount + amount, + 'KMD interest claim request', + 'KMD interest claim request', + true ] }; @@ -314,7 +317,7 @@ export function sendFromPromise(coin, address, amount) { console.log(error); dispatch( triggerToaster( - 'sendFrom', + 'sendToAddress', 'Error', 'error' ) @@ -322,7 +325,7 @@ export function sendFromPromise(coin, address, amount) { }) .then(response => response.json()) .then(json => { - resolve(json.result ? json.result : json); + resolve(json); }) }); } \ No newline at end of file diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js index 95b70bb..94e05f5 100755 --- a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js @@ -6,7 +6,8 @@ import { getListUnspent, getRawTransaction, copyString, - sendFromPromise + sendToAddressPromise, + triggerToaster } from '../../../actions/actionCreators'; import { translate } from '../../../translate/translate'; import { @@ -36,12 +37,12 @@ class ClaimInterestModal extends React.Component { loadListUnspent() { let _transactionsList = []; - getListUnspent('KMD') + getListUnspent(this.props.ActiveCoin.coin) .then((json) => { if (json && json.length) { for (let i = 0; i < json.length; i++) { - getRawTransaction('KMD', json[i].txid) + getRawTransaction(this.props.ActiveCoin.coin, json[i].txid) .then((_json) => { _transactionsList.push({ address: json[i].address, @@ -64,11 +65,28 @@ class ClaimInterestModal extends React.Component { } claimInterest(address, amount) { - console.warn('claim interest', `${address} ${amount}`); - /*sendFromPromise(address, amount) + sendToAddressPromise(this.props.ActiveCoin.coin, this.state.transactionsList[0].address, this.props.ActiveCoin.balance.transparent) .then((json) => { - console.warn(json); - });*/ + if (json.error && + json.error.code) { + Store.dispatch( + triggerToaster( + json.error.message, + 'Error', + 'error' + ) + ); + } else if (json.result && json.result.length && json.result.length === 64) { + Store.dispatch( + triggerToaster( + `Your full balance is sent to address ${this.state.transactionsList[0].address}. Check back your new balance in a few minutes.`, + translate('TOASTR.WALLET_NOTIFICATION'), + 'success', + false + ) + ); + } + }); } checkTransactionsListLength() { diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js index 8872fc2..8754965 100644 --- a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js @@ -30,14 +30,6 @@ export const _ClaimInterestTableRender = function() { } - - - ); } @@ -46,7 +38,7 @@ export const _ClaimInterestTableRender = function() { return (
    - Requirements to accure interest: locktime field is set and amount is greater than 10 KMD + Requirements to accrue interest: locktime field is set and amount is greater than 10 KMD
    +
    @@ -72,7 +70,6 @@ export const _ClaimInterestTableRender = function() { - @@ -85,7 +82,6 @@ export const _ClaimInterestTableRender = function() { -
    Amount Interest Locktime
    Amount Interest Locktime
    @@ -94,10 +90,6 @@ export const _ClaimInterestTableRender = function() { ); }; - //{ this.renderAddressList('public') } - //{ this.isNativeMode() && this.renderAddressList('private') } - - export const ClaimInterestModalRender = function() { return ( diff --git a/react/src/components/dashboard/jumblr/jumblr.js b/react/src/components/dashboard/jumblr/jumblr.js index d75b948..a69dbd1 100755 --- a/react/src/components/dashboard/jumblr/jumblr.js +++ b/react/src/components/dashboard/jumblr/jumblr.js @@ -169,7 +169,7 @@ class Jumblr extends React.Component { json.error.code) { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -299,7 +299,7 @@ class Jumblr extends React.Component { } else { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -348,7 +348,7 @@ class Jumblr extends React.Component { json.error.code) { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -372,7 +372,7 @@ class Jumblr extends React.Component { } else { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index ed599ec..b074e1f 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -851,6 +851,11 @@ select{ padding: 8px 30px 8px 0; } + .claim-btn { + position: absolute; + right: 29px; + top: 66px; + } .table-scroll { height: 366px; overflow-y: auto; From 346fb0a229721c880ffd7b182c117d8dfda6e06f Mon Sep 17 00:00:00 2001 From: pbca26 Date: Tue, 15 Aug 2017 20:21:19 +0300 Subject: [PATCH 57/58] asset chain crash handler --- react/src/actions/actions/nativeSyncInfo.js | 13 +++++++++++-- react/src/actions/actions/settings.js | 6 +++++- .../coindDownModal/coindDownModal.render.js | 2 +- react/src/components/overrides.scss | 9 ++++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index b75b161..009c190 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -182,7 +182,12 @@ export function getSyncInfoNative(coin, skipDebug) { true ) ); - dispatch(getDebugLog('komodo', 50)); + + if (coin === 'KMD') { + dispatch(getDebugLog('komodo', 50)); + } else { + dispatch(getDebugLog('komodo', 50, coin)); + } dispatch(toggleCoindDownModal(true)); } else { json = JSON.parse(json); @@ -190,7 +195,11 @@ export function getSyncInfoNative(coin, skipDebug) { if (json.error && json.error.message.indexOf('Activating best') === -1) { - dispatch(getDebugLog('komodo', 1)); + if (coin === 'KMD') { + dispatch(getDebugLog('komodo', 1)); + } else { + dispatch(getDebugLog('komodo', 1, coin)); + } } if (Config.debug) { diff --git a/react/src/actions/actions/settings.js b/react/src/actions/actions/settings.js index f38adfa..2b53637 100644 --- a/react/src/actions/actions/settings.js +++ b/react/src/actions/actions/settings.js @@ -167,12 +167,16 @@ function getDebugLogState(json) { } } -export function getDebugLog(target, linesCount) { +export function getDebugLog(target, linesCount, acName) { const payload = { 'herdname': target, 'lastLines': linesCount }; + if (acName) { + payload['ac'] = acName; + } + return dispatch => { return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/debuglog`, { method: 'POST', diff --git a/react/src/components/dashboard/coindDownModal/coindDownModal.render.js b/react/src/components/dashboard/coindDownModal/coindDownModal.render.js index 548e661..3787039 100644 --- a/react/src/components/dashboard/coindDownModal/coindDownModal.render.js +++ b/react/src/components/dashboard/coindDownModal/coindDownModal.render.js @@ -16,7 +16,7 @@ const CoindDownModalRender = function () { onClick={ this.dismiss }> × -

    Komodod is down!

    +

    { this.props.ActiveCoin.coin === 'KMD' ? 'Komodod' : `Komodod / ${this.props.ActiveCoin.coin}` } is down!

    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index b074e1f..6d1ea2f 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -629,12 +629,19 @@ select{ > div { height: 100%; } + .form-group { + &.form-material { + &.floating { + height: 80%; + } + } + } .page-content { width: 90%; height: 100%; textarea { - min-height: 200px; + height: 100%; } } } From a23618cc5a83dea9ba23c58d7b6272c0b542a3b9 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 16 Aug 2017 11:14:47 +0300 Subject: [PATCH 58/58] updated change.log --- react/change.log | 1 + 1 file changed, 1 insertion(+) diff --git a/react/change.log b/react/change.log index 239bf47..5ee34f5 100644 --- a/react/change.log +++ b/react/change.log @@ -19,6 +19,7 @@ UI: - added coqui assetchain - jumblr - zcashparams folder check +- claim interest modal v0.2.0.21a-beta --------------