diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js
index 69d451c..68e99e4 100644
--- a/react/src/actions/actionCreators.js
+++ b/react/src/actions/actionCreators.js
@@ -68,6 +68,7 @@ export * from './actions/basiliskTxHistory';
export * from './actions/iguanaHelpers';
export * from './actions/cli';
export * from './actions/update';
+export * from './actions/jumblr';
export function changeActiveAddress(address) {
return {
diff --git a/react/src/actions/actions/copyAddress.js b/react/src/actions/actions/copyAddress.js
index 9bf15fe..9accd3b 100644
--- a/react/src/actions/actions/copyAddress.js
+++ b/react/src/actions/actions/copyAddress.js
@@ -14,4 +14,18 @@ export function copyCoinAddress(address) {
)
);
}
+}
+
+export function copyString(string, message) {
+ const _result = copyToClipboard(string);
+
+ return dispatch => {
+ dispatch(
+ triggerToaster(
+ message,
+ translate('TOASTR.COIN_NOTIFICATION'),
+ _result ? 'success' : 'error'
+ )
+ );
+ }
}
\ No newline at end of file
diff --git a/react/src/actions/actions/jumblr.js b/react/src/actions/actions/jumblr.js
new file mode 100644
index 0000000..c734c07
--- /dev/null
+++ b/react/src/actions/actions/jumblr.js
@@ -0,0 +1,164 @@
+import {
+ triggerToaster,
+ getNewKMDAddresses
+} from '../actionCreators';
+import {
+ logGuiHttp,
+ guiLogState
+} from './log';
+import Config from '../../config';
+
+function getNewAddress(coin) { // TODO: remove(?)
+ return new Promise((resolve, reject) => {
+ const payload = {
+ mode: null,
+ chain: coin,
+ cmd: 'getnewaddress'
+ };
+
+ 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(
+ 'genJumblrAddress + getKMDAddressesNative',
+ 'Error',
+ 'error'
+ )
+ );
+ })
+ .then(response => response.json())
+ .then(json => {
+ resolve(json.result ? json.result : json);
+ })
+ });
+}
+
+export function setJumblrAddress(coin, type, address) {
+ return new Promise((resolve, reject) => {
+ const payload = {
+ mode: null,
+ chain: coin,
+ cmd: type === 'deposit' ? 'jumblr_deposit' : 'jumblr_secret',
+ params: [address],
+ };
+
+ 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(
+ 'setJumblrAddress',
+ 'Error',
+ 'error'
+ )
+ );
+ })
+ .then(response => response.json())
+ .then(json => {
+ resolve(json);
+ });
+ });
+}
+
+function dumpPrivkey(coin, key) {
+ return new Promise((resolve, reject) => {
+ const payload = {
+ mode: null,
+ chain: coin,
+ cmd: 'dumpprivkey',
+ params: [key],
+ };
+
+ 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(
+ 'dumpPrivkey ',
+ 'Error',
+ 'error'
+ )
+ );
+ })
+ .then(response => response.json())
+ .then(json => {
+ resolve(json.result ? json.result : json);
+ })
+ });
+}
+
+export function importPrivkey(coin, key) {
+ return new Promise((resolve, reject) => {
+ const payload = {
+ mode: null,
+ chain: coin,
+ cmd: 'importprivkey',
+ params: [
+ key,
+ '',
+ false
+ ],
+ };
+
+ 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(
+ 'importPrivkey ',
+ '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/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js
index 4bd4088..e3f9821 100644
--- a/react/src/actions/actions/nativeNewAddress.js
+++ b/react/src/actions/actions/nativeNewAddress.js
@@ -10,21 +10,7 @@ import {
guiLogState
} from './log';
-function handleGetNewKMDAddresses(pubpriv, coin, dispatch, json) {
- dispatch(
- triggerToaster(
- json.result ? json.result : json,
- translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
- 'info',
- false
- )
- );
- dispatch(getKMDAddressesNative(coin));
-
- return {};
-}
-
-export function getNewKMDAddresses(coin, pubpriv) {
+export function getNewKMDAddresses(coin, pubpriv, mode) {
let payload;
let ajaxFunctionInput = pubpriv === 'public' ? 'getnewaddress' : 'z_getnewaddress';
@@ -115,22 +101,25 @@ export function getNewKMDAddresses(coin, pubpriv) {
}));
}
dispatch(
- handleGetNewKMDAddresses(
- pubpriv,
- coin,
- dispatch,
- json
+ triggerToaster(
+ json.result ? json.result : json,
+ translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
+ 'info',
+ false
)
);
+ dispatch(getKMDAddressesNative(coin, mode));
})
.catch(function(ex) {
dispatch(
- handleGetNewKMDAddresses(
- pubpriv,
- coin,
- dispatch
+ triggerToaster(
+ json.result ? json.result : json,
+ translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
+ 'info',
+ false
)
);
+ dispatch(getKMDAddressesNative(coin, mode));
});
}
}
\ No newline at end of file
diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js
index 8260128..196ef53 100644
--- a/react/src/actions/actions/nativeSyncInfo.js
+++ b/react/src/actions/actions/nativeSyncInfo.js
@@ -11,7 +11,7 @@ import {
} from './log';
import Config from '../../config';
-export function getSyncInfoNativeKMD(skipDebug) {
+export function getSyncInfoNativeKMD(skipDebug, json) {
const coin = 'KMD';
return dispatch => {
@@ -40,13 +40,15 @@ export function getSyncInfoNativeKMD(skipDebug) {
'response': error,
}));
}
- dispatch(
+ /*dispatch(
triggerToaster(
'getSyncInfoNativeKMD',
'Error',
'error'
)
- );
+ );*/
+ console.warn('remote kmd node fetch failed', true);
+ dispatch(getSyncInfoNativeState({ 'remoteKMDNode': null }));
})
.then(response => response.json())
.then(json => {
@@ -72,7 +74,7 @@ function getSyncInfoNativeState(json, coin, skipDebug) {
json &&
json.error &&
json.error.message.indexOf('Activating best') === -1) {
- return getSyncInfoNativeKMD(skipDebug);
+ return getSyncInfoNativeKMD(skipDebug, json);
} else {
if (json &&
json.error &&
@@ -161,41 +163,51 @@ export function getSyncInfoNative(coin, skipDebug) {
return _response;
})
.then(json => {
- if (!json &&
- Config.cli.default) {
+ if (json === 'Work queue depth exceeded') {
dispatch(
- triggerToaster(
- 'Komodod is down',
- 'Critical Error',
- 'error',
- true
+ getSyncInfoNativeState(
+ { result: 'daemon is busy', error: null, id: null },
+ coin,
+ skipDebug
)
);
- dispatch(getDebugLog('komodo', 50));
- dispatch(toggleCoindDownModal(true));
} else {
- json = JSON.parse(json);
- }
+ if (!json &&
+ Config.cli.default) {
+ dispatch(
+ triggerToaster(
+ 'Komodod is down',
+ 'Critical Error',
+ 'error',
+ true
+ )
+ );
+ dispatch(getDebugLog('komodo', 50));
+ dispatch(toggleCoindDownModal(true));
+ } else {
+ json = JSON.parse(json);
+ }
- if (json.error &&
- json.error.message.indexOf('Activating best') === -1) {
- dispatch(getDebugLog('komodo', 1));
- }
+ if (json.error &&
+ json.error.message.indexOf('Activating best') === -1) {
+ dispatch(getDebugLog('komodo', 1));
+ }
- if (Config.debug) {
- dispatch(logGuiHttp({
- 'timestamp': _timestamp,
- 'status': 'success',
- 'response': json,
- }));
+ if (Config.debug) {
+ dispatch(logGuiHttp({
+ 'timestamp': _timestamp,
+ 'status': 'success',
+ 'response': json,
+ }));
+ }
+ dispatch(
+ getSyncInfoNativeState(
+ json,
+ coin,
+ skipDebug
+ )
+ );
}
- dispatch(
- getSyncInfoNativeState(
- json,
- coin,
- skipDebug
- )
- );
})
}
}
\ No newline at end of file
diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js
index e270774..b43c1d1 100644
--- a/react/src/components/dashboard/coinTile/coinTileItem.js
+++ b/react/src/components/dashboard/coinTile/coinTileItem.js
@@ -111,6 +111,11 @@ class CoinTileItem extends React.Component {
setTimeout(() => {
this.dispatchCoinActions(coin, mode);
}, 100);
+ if (mode === 'native') { // faster coin data load if fully synced
+ setTimeout(() => {
+ this.dispatchCoinActions(coin, mode);
+ }, 1000);
+ }
Store.dispatch(
stopInterval(
@@ -141,7 +146,7 @@ class CoinTileItem extends React.Component {
if (mode === 'native') {
const _iguanaActiveHandle = setInterval(() => {
this.dispatchCoinActions(coin, mode);
- }, coin === 'KMD' ? IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE : IGUNA_ACTIVE_HANDLE_TIMEOUT);
+ }, IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE);
Store.dispatch(startInterval('sync', _iguanaActiveHandle));
}
diff --git a/react/src/components/dashboard/jumblr/jumblr.js b/react/src/components/dashboard/jumblr/jumblr.js
index 4ae03a0..d75b948 100755
--- a/react/src/components/dashboard/jumblr/jumblr.js
+++ b/react/src/components/dashboard/jumblr/jumblr.js
@@ -1,14 +1,391 @@
import React from 'react';
import { translate } from '../../../translate/translate';
+import {
+ dashboardChangeActiveCoin,
+ getKMDAddressesNative,
+ startInterval,
+ stopInterval,
+ triggerToaster,
+ setJumblrAddress,
+ importPrivkey,
+ copyCoinAddress,
+ copyString
+} from '../../../actions/actionCreators';
+import Store from '../../../store';
+import Config from '../../../config';
+import {
+ JumblrRender,
+ JumblrRenderSecretAddressList
+} from './jumblr.render';
+import { PassPhraseGenerator } from '../../../util/crypto/passphrasegenerator';
-import JumblrRender from './jumblr.render';
+// import gen komodo keys utils
+import '../../../util/crypto/gen/array.map.js';
+import '../../../util/crypto/gen/cryptojs.js';
+import '../../../util/crypto/gen/cryptojs.sha256.js';
+import '../../../util/crypto/gen/cryptojs.pbkdf2.js';
+import '../../../util/crypto/gen/cryptojs.hmac.js';
+import '../../../util/crypto/gen/cryptojs.aes.js';
+import '../../../util/crypto/gen/cryptojs.blockmodes.js';
+import '../../../util/crypto/gen/cryptojs.ripemd160.js';
+import '../../../util/crypto/gen/securerandom.js';
+import '../../../util/crypto/gen/ellipticcurve.js';
+import '../../../util/crypto/gen/biginteger.js';
+import '../../../util/crypto/gen/crypto-scrypt.js';
+import { Bitcoin } from '../../../util/crypto/gen/bitcoin.js';
+
+if (!window.jumblrPasshrase) { // gen jumblr passphrase
+ window.jumblrPasshrase = 'jumblr ' + PassPhraseGenerator.generatePassPhrase(256);
+}
class Jumblr extends React.Component {
constructor(props) {
super(props);
this.state = {
activeTab: 0,
+ randomSeed: window.jumblrPasshrase,
+ jumblrDepositAddress: null,
+ jumblrDepositAddressPBased: true,
+ jumblrSecretAddressShow: true,
+ jumblrSecretAddress: [],
+ jumblrSecretAddressImport: [],
+ jumblrSecretAddressCountImport: 0,
+ jumblrSecretAddressShowImport: true,
+ jumblrSecretAddressCount: 0,
+ jumblrMode: 'public',
+ secretAddressCount: 1,
+ secretAddressCountImport: 1,
+ jumblrPassphraseImport: '',
+ };
+ this.generateJumblrDepositAddress = this.generateJumblrDepositAddress.bind(this);
+ this.generateJumblrSecretAddress = this.generateJumblrSecretAddress.bind(this);
+ this.checkJumblrSecretAddressListLength = this.checkJumblrSecretAddressListLength.bind(this);
+ this.returnPassphrase = this.returnPassphrase.bind(this);
+ this.generateKeys = this.generateKeys.bind(this);
+ this._copyCoinAddress = this._copyCoinAddress.bind(this);
+ this.copyPassphrase = this.copyPassphrase.bind(this);
+ this.checkPassphraseValid = this.checkPassphraseValid.bind(this);
+ this.importJumblrSecretAddress = this.importJumblrSecretAddress.bind(this);
+ this.onChange = this.onChange.bind(this);
+ }
+
+ generateKeys(passphrase) {
+ if (!passphrase) {
+ const key = new Bitcoin.ECKey(false).setCompressed(true);
+ const kmdAddress = key.getBitcoinAddress();
+ const wifAddress = key.getBitcoinWalletImportFormat();
+
+ return {
+ address: kmdAddress,
+ wif: wifAddress,
+ };
+ } else {
+ const bytes = Crypto.SHA256(passphrase, { asBytes: true });
+ const btcKey = new Bitcoin.ECKey(bytes).setCompressed(true);
+ const kmdAddress = btcKey.getBitcoinAddress();
+ const wifAddress = btcKey.getBitcoinWalletImportFormat();
+
+ return {
+ address: kmdAddress,
+ wif: wifAddress,
+ };
+ }
+ }
+
+ _JumblrRenderSecretAddressList(type) {
+ return JumblrRenderSecretAddressList.call(this, type);
+ }
+
+ onChange(e) {
+ const regex = /^[0-9\b]+$/;
+
+ if (e.target.value === '' ||
+ regex.test(e.target.value)) {
+ this.setState({
+ [e.target.name]: e.target.value,
+ });
+ }
+ }
+
+ passphraseOnChange(e) {
+ this.setState({
+ [e.target.name]: e.target.value,
+ });
+ }
+
+ returnPassphrase() {
+ this.setState({
+ randomSeed: window.jumblrPasshrase,
+ });
+ }
+
+ toggle(prop) {
+ const _prop = this.state[prop];
+
+ this.setState({
+ [prop]: !_prop,
+ });
+ }
+
+ /*toggleAddressGenMod() {
+ this.setState({
+ jumblrDepositAddressPBased: !this.state.jumblrDepositAddressPBased,
+ });
+ }*/
+
+ generateJumblrSecretAddress() {
+ let _jumblrSecretAddress = [];
+ let _apiSuccessCount = 0;
+
+ if (this.state.secretAddressCount === '') {
+ Store.dispatch(
+ triggerToaster(
+ 'Enter a correct address count value',
+ 'Jumblr',
+ 'error'
+ )
+ );
+ } else {
+ for (let i = 0; i < this.state.secretAddressCount; i++) {
+ let _genKeys;
+
+ if (this.state.jumblrDepositAddressPBased) {
+ let _postfix;
+
+ if (i < 9) {
+ _postfix = `00${i + 1}`;
+ } else if (i > 10 && i < 100) {
+ _postfix = `0${i + 1}`;
+ }
+ _genKeys = this.generateKeys(`${this.state.randomSeed} ${_postfix}`);
+ // console.warn(`${this.state.randomSeed} ${_postfix}`);
+ } else {
+ _genKeys = this.generateKeys();
+ }
+
+ setJumblrAddress(this.props.ActiveCoin.coin, 'secret', _genKeys.address)
+ .then((json) => {
+ if (json.error &&
+ json.error.code) {
+ Store.dispatch(
+ triggerToaster(
+ json.error.code,
+ 'Error',
+ 'error'
+ )
+ );
+ } else if (json.result && json.result.result && json.result.result === 'success') {
+ _jumblrSecretAddress.push(_genKeys);
+ this.setState(Object.assign({}, this.state, {
+ jumblrSecretAddress: _jumblrSecretAddress,
+ }));
+
+ if (_apiSuccessCount === this.state.secretAddressCount - 1) {
+ Store.dispatch(
+ triggerToaster(
+ this.state.secretAddressCount > 1 ? 'Jumblr secret addresses are set' : 'Jumblr secret address is set',
+ 'Jumblr',
+ 'success'
+ )
+ );
+ }
+ _apiSuccessCount++;
+ }
+ });
+ }
+ }
+ }
+
+ checkPassphraseValid() { // test passphrase validity
+ const _passphrase = this.state.jumblrPassphraseImport;
+ const _jumblrPrefix = _passphrase.substring(0, 6);
+ const _passphraseWords = _passphrase.substring(6, _passphrase.length);
+ let _errors = {
+ prefix: false, // jumblr
+ length: false, // 24
};
+
+ if (_jumblrPrefix !== 'jumblr') {
+ _errors.prefix = true;
+ }
+
+ try {
+ const _passphraseWordsSplit = _passphraseWords.split(' ');
+ let _correctWords = 0;
+
+ if (_passphraseWordsSplit &&
+ _passphraseWordsSplit.length) {
+ for (let i = 0; i < _passphraseWordsSplit.length; i++) {
+ if (_passphraseWordsSplit[i].length > 2) {
+ _correctWords++;
+ }
+ }
+
+ if (_correctWords !== _passphraseWordsSplit.length - 1 || _correctWords !== 24) {
+ _errors.length = true;
+ }
+ } else {
+ _errors.length = true;
+ }
+ } catch(e) {
+ _errors.length = true;
+ }
+
+
+ if (_errors.length ||
+ _errors.prefix) {
+ Store.dispatch(
+ triggerToaster(
+ 'Provided passphrase has wrong format',
+ 'Jumblr',
+ 'error',
+ false
+ )
+ );
+
+ return false;
+ }
+
+ return true;
+ }
+
+ importJumblrSecretAddress() {
+ let _jumblrSecretAddress = [];
+ let _apiSuccessCount = 0;
+
+ if (this.state.secretAddressCountImport === '') {
+ Store.dispatch(
+ triggerToaster(
+ 'Enter a correct address count value',
+ 'Jumblr',
+ 'error'
+ )
+ );
+ } else {
+ if (this.checkPassphraseValid()) {
+ for (let i = 0; i < this.state.secretAddressCountImport; i++) {
+ let _genKeys;
+
+ if (this.state.jumblrDepositAddressPBased) {
+ let _postfix;
+
+ if (i < 9) {
+ _postfix = `00${i + 1}`;
+ } else if (i > 10 && i < 100) {
+ _postfix = `0${i + 1}`;
+ }
+ _genKeys = this.generateKeys(`${this.state.jumblrPassphraseImport} ${_postfix}`);
+ } else {
+ _genKeys = this.generateKeys();
+ }
+
+ importPrivkey(this.props.ActiveCoin.coin, _genKeys.wif)
+ .then((json) => {
+ if (!json.id && !json.result && !json.error) {
+ _jumblrSecretAddress.push(_genKeys);
+ this.setState(Object.assign({}, this.state, {
+ jumblrSecretAddressImport: _jumblrSecretAddress,
+ }));
+ if (_apiSuccessCount === this.state.secretAddressCountImport - 1) {
+ Store.dispatch(
+ triggerToaster(
+ this.state.secretAddressCountImport > 1 ? 'Jumblr secret addresses imported' : 'Jumblr secret address imported',
+ 'Jumblr',
+ 'success'
+ )
+ );
+ }
+ _apiSuccessCount++;
+ } else {
+ Store.dispatch(
+ triggerToaster(
+ json.error.code,
+ 'Error',
+ 'error'
+ )
+ );
+ }
+ });
+ }
+ }
+ }
+ }
+
+ checkJumblrSecretAddressListLength(type) {
+ if (type === 'gen') {
+ if (this.state.jumblrSecretAddress &&
+ this.state.jumblrSecretAddress.length) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if (this.state.jumblrSecretAddressImport &&
+ this.state.jumblrSecretAddressImport.length) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ generateJumblrDepositAddress() {
+ let _genKeys;
+
+ if (this.state.jumblrDepositAddressPBased) {
+ _genKeys = this.generateKeys(this.state.randomSeed);
+ } else {
+ _genKeys = this.generateKeys();
+ }
+
+ importPrivkey(this.props.ActiveCoin.coin, _genKeys.wif)
+ .then((json) => {
+ if (!json.id && !json.result && !json.error) {
+ // console.warn('importPrivkey', json);
+ setJumblrAddress(this.props.ActiveCoin.coin, 'deposit', _genKeys.address)
+ .then((json) => {
+ if (json.error &&
+ json.error.code) {
+ Store.dispatch(
+ triggerToaster(
+ json.error.code,
+ 'Error',
+ 'error'
+ )
+ );
+ } else if (json.result && json.result.result === 0) {
+ this.setState(Object.assign({}, this.state, {
+ jumblrDepositAddress: {
+ address: _genKeys.address,
+ wif: _genKeys.wif,
+ },
+ }));
+ Store.dispatch(
+ triggerToaster(
+ 'Jumblr deposit address is set',
+ 'Jumblr',
+ 'success'
+ )
+ );
+ }
+ });
+ } else {
+ Store.dispatch(
+ triggerToaster(
+ json.error.code,
+ 'Error',
+ 'error'
+ )
+ );
+ }
+ });
+ }
+
+ switchJumblrMode(mode) {
+ this.setState(Object.assign({}, this.state, {
+ jumblrMode: mode,
+ activeTab: 0,
+ }));
}
openTab(tab) {
@@ -17,6 +394,14 @@ class Jumblr extends React.Component {
}));
}
+ _copyCoinAddress(address) {
+ Store.dispatch(copyCoinAddress(address));
+ }
+
+ copyPassphrase() {
+ Store.dispatch(copyString(this.state.randomSeed, 'Passphrase copied'));
+ }
+
renderLB(_translationID) {
const _translationComponents = translate(_translationID).split('
');
diff --git a/react/src/components/dashboard/jumblr/jumblr.render.js b/react/src/components/dashboard/jumblr/jumblr.render.js
index 846400d..fab7b1c 100644
--- a/react/src/components/dashboard/jumblr/jumblr.render.js
+++ b/react/src/components/dashboard/jumblr/jumblr.render.js
@@ -2,10 +2,53 @@ import React from 'react';
import { translate } from '../../../translate/translate';
import WalletsHeader from '../walletsHeader/walletsHeader';
+import WalletsNativeSend from '../walletsNativeSend/walletsNativeSend';
+import ReceiveCoin from '../receiveCoin/receiveCoin';
-const JumblrRender = function() {
+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++) {
+ _items.push(
+
+ Jumblr functions all locally which means no middle man is required to jumble your funds. You take control over the whole process. +
++ Tip: to achive maximum anonimity setup Jumblr node on a dedicated piece of hardware (laptop or VPS), use a separate IP address for main Jumblr node. +
{ translate('JUMBLR.THIS_SCREEN_DOESNT_REFRESH') }
+{ translate('JUMBLR.ADDRESS_ACCESSIBLE_EASILY') }
-duck dog cat donkey
- jumblr duck dog cat donkey
- { translate('JUMBLR.TO_CLEAR_THEM') }
{ translate('JUMBLR.WHEN_IT_TOTALS') }
{ translate('JUMBLR.BTC_DEPOSIT') } | -- - | -
BTC Jumblr | -
+
+
+ { translate('JUMBLR.FEW_SECURITY_NOTES') }+
+
+ { this.state.jumblrDepositAddressPBased &&
+
+
+
+
+
-
- { translate('JUMBLR.HIDDEN') }
- + Please write down your Jumblr passphrase and keept it safe. + +This is your main recovery passphrase. +All Jumblr addresses can be regenrated based on it. +
+ Tip: do not use smart editors to store your passphrase as they tend to add extra characters. |
-
{ translate('JUMBLR.KMD_DEPOSIT') } | -- |
KMD Jumblr | -
+
+ }
+
+ { this.state.jumblrDepositAddress && this.state.jumblrDepositAddress.address &&
+
+ Your Jumblr deposit address:
+
+ }
+
+ + { this.state.jumblrDepositAddress.address } + + ++ { this.state.jumblrDepositAddress.wif } + + +
+
+ Jumblr secret addresses are used for the final z -> t transactions. +In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported. +Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected. +To add a new set of secret addresses enter address count below. The passphrase below is exactly the same you saw on the previous step. +Your Jumblr secret address recovery passphrase will have the following pattern
+
+
-
-
- { translate('JUMBLR.HIDDEN') }
-
- |
-
+ 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.
+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.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') } | -- |
+ Address + | ++ Wif + | +
{ translate('INDEX.STATUS') } | -ID | -{ translate('INDEX.TIME') } | -{ translate('INDEX.RESULT') } | -
---|---|---|---|
{ translate('INDEX.STATUS') } | -ID | -{ translate('INDEX.TIME') } | -{ translate('INDEX.RESULT') } | -
{ translate('INDEX.STATUS') } | +ID | +{ translate('INDEX.TIME') } | +{ translate('INDEX.RESULT') } | +
---|---|---|---|
{ translate('INDEX.STATUS') } | +ID | +{ translate('INDEX.TIME') } | +{ translate('INDEX.RESULT') } | +