diff --git a/images/bch-logo.png b/images/bch-logo.png
deleted file mode 100644
index 9590c12e..00000000
Binary files a/images/bch-logo.png and /dev/null differ
diff --git a/images/btc-logo.png b/images/btc-logo.png
deleted file mode 100644
index 5b77226c..00000000
Binary files a/images/btc-logo.png and /dev/null differ
diff --git a/images/btg-logo.png b/images/btg-logo.png
deleted file mode 100644
index 5eda4570..00000000
Binary files a/images/btg-logo.png and /dev/null differ
diff --git a/images/case.png b/images/case.png
deleted file mode 100644
index eee16f1d..00000000
Binary files a/images/case.png and /dev/null differ
diff --git a/images/dash-logo.png b/images/dash-logo.png
deleted file mode 100644
index 5c3a113d..00000000
Binary files a/images/dash-logo.png and /dev/null differ
diff --git a/images/etc-logo.png b/images/etc-logo.png
deleted file mode 100644
index e868d6ea..00000000
Binary files a/images/etc-logo.png and /dev/null differ
diff --git a/images/eth-logo.png b/images/eth-logo.png
deleted file mode 100644
index 5b7c1a8a..00000000
Binary files a/images/eth-logo.png and /dev/null differ
diff --git a/images/icontrezor.png b/images/icontrezor.png
deleted file mode 100644
index 8c35659b..00000000
Binary files a/images/icontrezor.png and /dev/null differ
diff --git a/images/ltc-logo.png b/images/ltc-logo.png
deleted file mode 100644
index 201f2350..00000000
Binary files a/images/ltc-logo.png and /dev/null differ
diff --git a/images/zec-logo.png b/images/zec-logo.png
deleted file mode 100644
index 134ba792..00000000
Binary files a/images/zec-logo.png and /dev/null differ
diff --git a/package.json b/package.json
index 55bc64da..62795433 100644
--- a/package.json
+++ b/package.json
@@ -21,29 +21,32 @@
},
"dependencies": {
"babel-preset-react": "^6.24.1",
+ "bowser": "^1.9.2",
"color-hash": "^1.0.3",
"ethereumjs-tx": "^1.3.3",
"ethereumjs-units": "^0.2.0",
- "ethereumjs-util": "^5.1.2",
- "hdkey": "0.7.1",
+ "ethereumjs-util": "^5.1.4",
+ "hdkey": "^0.8.0",
"path-to-regexp": "^2.1.0",
"raf": "^3.4.0",
+ "raven-js": "^3.22.3",
"rc-tooltip": "^3.7.0",
- "react": "^16.1.1",
+ "react": "^16.2.0",
"react-blockies": "^1.2.2",
"react-css-transition": "^0.7.4",
- "react-dom": "^16.1.1",
+ "react-dom": "^16.2.0",
"react-ellipsis-text": "^1.0.0",
"react-hot-loader": "^3.1.3",
"react-qr-svg": "^2.1.0",
- "react-redux": "^5.0.6",
+ "react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-router-redux": "next",
"react-scale-text": "^1.2.2",
- "react-select": "^1.1.0",
+ "react-select": "^1.2.1",
"react-transition-group": "^2.2.1",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
+ "redux-raven-middleware": "^1.2.0",
"redux-thunk": "^2.2.0",
"web3": "^0.19.0"
},
@@ -56,22 +59,22 @@
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-webpack-alias": "^2.1.2",
"babel-preset-env": "^1.6.0",
- "copy-webpack-plugin": "^4.0.1",
- "css-loader": "^0.28.4",
+ "copy-webpack-plugin": "^4.4.1",
+ "css-loader": "^0.28.9",
"express": "^4.15.3",
"extract-text-webpack-plugin": "^3.0.0",
- "file-loader": "^0.11.2",
+ "file-loader": "^1.1.9",
"html-webpack-plugin": "^2.29.0",
"json-loader": "^0.5.7",
- "less": "^2.7.2",
+ "less": "^3.0.1",
"less-loader": "^4.0.5",
"open": "^0.0.5",
- "style-loader": "^0.18.2",
- "webpack": "^3.4.1",
- "webpack-dev-middleware": "^1.11.0",
- "webpack-hot-middleware": "^2.18.0",
+ "style-loader": "^0.20.2",
+ "webpack": "3.11.0",
+ "webpack-dev-middleware": "2.0.5",
+ "webpack-hot-middleware": "2.21.0",
"webpack-merge": "^4.1.1",
"whatwg-fetch": "^2.0.3",
- "yargs": "^10.0.3"
+ "yargs": "11.0.0"
}
}
diff --git a/src/data/appConfig.json b/src/data/appConfig.json
index 2c9ce85b..3285f8a9 100644
--- a/src/data/appConfig.json
+++ b/src/data/appConfig.json
@@ -25,9 +25,8 @@
"coins": [
{
"name": "Ethereum Ropsten",
- "symbol": "eth",
- "network": "ropsten-eth",
- "shortcut": "eth",
+ "symbol": "tETH",
+ "network": "ropsten",
"bip44": "m/44'/60'/0'/0",
"defaultGasPrice": 64,
"defaultGasLimit": 21000,
@@ -38,16 +37,15 @@
"urls": [
"https://ropsten.infura.io/QGyVKozSUEh2YhL4s2G4",
"http://10.34.2.5:8545"
- ],
- "explorer": "https://blockexplorer.com"
+ ]
}
- ]
+ ],
+ "explorer": "https://ropsten.etherscan.io"
},
{
"name": "Ethereum Rinkeby",
- "symbol": "etc",
- "network": "ropsten-eth",
- "shortcut": "etc",
+ "symbol": "tETH",
+ "network": "rinkeby",
"bip44": "m/44'/61'/0'/0",
"defaultGasPrice": 64,
"defaultGasLimit": 21000,
@@ -56,19 +54,28 @@
{
"name": "TREZOR Wallet - Ethereum",
"urls": [
- "https://rinkeby.infura.io/QGyVKozSUEh2YhL4s2G4",
- "http://10.34.2.5:8545"
- ],
- "explorer": "https://blockexplorer.com"
+ "https://rinkeby.infura.io/QGyVKozSUEh2YhL4s2G4"
+ ]
}
- ]
+ ],
+ "explorer": "https://rinkeby.etherscan.io"
}
],
"fiatValueTickers": [
-
+ {
+ "network": "ropsten",
+ "url": "https://api.coinmarketcap.com/v1/ticker/ethereum/"
+ },
+ {
+ "network": "rinkeby",
+ "url": "https://api.coinmarketcap.com/v1/ticker/ethereum-classic/"
+ }
],
+
+
+
"bridge": {
"url": "https://localback.net:21324",
"configUrl": "data/config_signed.bin",
@@ -76,6 +83,20 @@
},
"extensionId": "jcjjhjgimijdkoamemaghajlhegmoclj",
"storageVersion": "1.1.0",
- "metadataVersion": "1.0.0"
+ "metadataVersion": "1.0.0",
+
+
+ "supportedBrowsers": {
+ "chrome": {
+ "version": 59,
+ "download": "https://www.google.com/chrome/",
+ "update": "https://support.google.com/chrome/answer/95414"
+ },
+ "firefox": {
+ "version": 54,
+ "download": "https://www.mozilla.org/en-US/firefox/new/",
+ "update": "https://support.mozilla.org/en-US/kb/update-firefox-latest-version"
+ }
+ }
}
\ No newline at end of file
diff --git a/src/fonts/glyphicons.eot b/src/fonts/glyphicons.eot
deleted file mode 100755
index 56792f69..00000000
Binary files a/src/fonts/glyphicons.eot and /dev/null differ
diff --git a/src/fonts/glyphicons.svg b/src/fonts/glyphicons.svg
deleted file mode 100755
index 48cddc5a..00000000
--- a/src/fonts/glyphicons.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/fonts/glyphicons.ttf b/src/fonts/glyphicons.ttf
deleted file mode 100755
index f1c30440..00000000
Binary files a/src/fonts/glyphicons.ttf and /dev/null differ
diff --git a/src/fonts/glyphicons.woff b/src/fonts/glyphicons.woff
deleted file mode 100755
index a0fa4cb6..00000000
Binary files a/src/fonts/glyphicons.woff and /dev/null differ
diff --git a/src/fonts/icomoon.eot b/src/fonts/icomoon.eot
index 153870a4..d2e31941 100755
Binary files a/src/fonts/icomoon.eot and b/src/fonts/icomoon.eot differ
diff --git a/src/fonts/icomoon.svg b/src/fonts/icomoon.svg
index 05e7fc9c..d4bb26cc 100755
--- a/src/fonts/icomoon.svg
+++ b/src/fonts/icomoon.svg
@@ -18,24 +18,25 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/fonts/icomoon.ttf b/src/fonts/icomoon.ttf
index 1e3aa3a8..3e7342b4 100755
Binary files a/src/fonts/icomoon.ttf and b/src/fonts/icomoon.ttf differ
diff --git a/src/fonts/icomoon.woff b/src/fonts/icomoon.woff
index 65c1cc49..17be113b 100755
Binary files a/src/fonts/icomoon.woff and b/src/fonts/icomoon.woff differ
diff --git a/src/fonts/pass.ttf b/src/fonts/pass.ttf
deleted file mode 100644
index c0f50b1b..00000000
Binary files a/src/fonts/pass.ttf and /dev/null differ
diff --git a/src/images/T.png b/src/images/T.png
new file mode 100644
index 00000000..54fdab30
Binary files /dev/null and b/src/images/T.png differ
diff --git a/src/images/bth-logo.png b/src/images/bth-logo.png
deleted file mode 100644
index dcc596e2..00000000
Binary files a/src/images/bth-logo.png and /dev/null differ
diff --git a/src/images/case.png b/src/images/case.png
index eee16f1d..93b69b18 100644
Binary files a/src/images/case.png and b/src/images/case.png differ
diff --git a/src/images/icons-spritesheet.svg b/src/images/icons-spritesheet.svg
deleted file mode 100644
index 337b1466..00000000
--- a/src/images/icons-spritesheet.svg
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
diff --git a/src/images/landingpage.png b/src/images/landingpage.png
deleted file mode 100644
index 43e64752..00000000
Binary files a/src/images/landingpage.png and /dev/null differ
diff --git a/src/index.html b/src/index.html
index 257d119f..53f5fb92 100644
--- a/src/index.html
+++ b/src/index.html
@@ -4,7 +4,7 @@
-
Ethereum Wallet| TREZOR
+ Ethereum Wallet | TREZOR
diff --git a/src/js/actions/LocalStorageActions.js b/src/js/actions/LocalStorageActions.js
index e6d2203c..bfe8a594 100644
--- a/src/js/actions/LocalStorageActions.js
+++ b/src/js/actions/LocalStorageActions.js
@@ -35,7 +35,6 @@ export function loadTokensFromJSON(): any {
const ethERC20 = await httpRequest('data/ethERC20.json', 'json');
const devices: ?string = get('devices');
- console.log("GET23", JSON.parse(devices))
if (devices) {
dispatch({
type: CONNECT.DEVICE_FROM_STORAGE,
@@ -59,6 +58,14 @@ export function loadTokensFromJSON(): any {
})
}
+ const pending: ?string = get('pending');
+ if (pending) {
+ dispatch({
+ type: 'PENDING.FROM_STORAGE',
+ payload: JSON.parse(pending)
+ })
+ }
+
const discovery: ?string = get('discovery');
if (discovery) {
dispatch({
@@ -88,12 +95,11 @@ export function loadTokensFromJSON(): any {
export const save = (key: string, value: string): any => {
return (dispatch, getState) => {
if (typeof window.localStorage !== 'undefined') {
- //console.log("SAVEE!!!!", key, value)
try {
window.localStorage.setItem(key, value);
} catch (error) {
// available = false;
- console.error("ERROR: " + error)
+ console.error("Local Storage ERROR: " + error)
}
}
}
@@ -102,7 +108,6 @@ export const save = (key: string, value: string): any => {
export const get = (key: string): ?string => {
if (typeof window.localStorage !== 'undefined') {
try {
- console.log("GETTT", JSON.parse(window.localStorage.getItem(key)))
return window.localStorage.getItem(key);
} catch (error) {
// available = false;
diff --git a/src/js/actions/LogActions.js b/src/js/actions/LogActions.js
new file mode 100644
index 00000000..216f88e6
--- /dev/null
+++ b/src/js/actions/LogActions.js
@@ -0,0 +1,15 @@
+/* @flow */
+'use strict';
+
+export const toggle = (): any => {
+ return (dispatch, getState) => {
+
+ if (!getState().log.opened) {
+ window.scrollTo(0, 0);
+ }
+
+ dispatch({
+ type: getState().log.opened ? 'log__close' : 'log__open'
+ });
+ }
+}
diff --git a/src/js/actions/ReceiveActions.js b/src/js/actions/ReceiveActions.js
index 4ee0ee7c..33a7043e 100644
--- a/src/js/actions/ReceiveActions.js
+++ b/src/js/actions/ReceiveActions.js
@@ -65,6 +65,7 @@ export const showAddress = (address_n: string): any => {
return async (dispatch, getState) => {
const selected = findSelectedDevice(getState().connect);
+ if (!selected) return;
if (selected && !selected.connected) {
dispatch({
diff --git a/src/js/actions/SendFormActions.js b/src/js/actions/SendFormActions.js
index f923ce7c..7b9eecf3 100644
--- a/src/js/actions/SendFormActions.js
+++ b/src/js/actions/SendFormActions.js
@@ -4,7 +4,7 @@
import * as SEND from './constants/SendForm';
import * as NOTIFICATION from './constants/notification';
-import { getNonce, estimateGas, getGasPrice, pushTx } from './Web3Actions';
+import { estimateGas, getGasPrice, pushTx } from './Web3Actions';
import EthereumjsUtil from 'ethereumjs-util';
import EthereumjsUnits from 'ethereumjs-units';
@@ -18,7 +18,8 @@ import { initialState } from '../reducers/SendFormReducer';
import type { State, FeeLevel } from '../reducers/SendFormReducer';
import { findSelectedDevice } from '../reducers/TrezorConnectReducer';
-const numberRegExp = new RegExp('^([0-9]{0,10}\\.)?[0-9]{1,18}$');
+//const numberRegExp = new RegExp('^([0-9]{0,10}\\.)?[0-9]{1,18}$');
+const numberRegExp = new RegExp('^(0|0\\.([0-9]+)?|[1-9]+\\.?([0-9]+)?|\\.[0-9]+)$');
const calculateFee = (gasPrice: string, gasLimit: string): string => {
return EthereumjsUnits.convert( new BigNumber(gasPrice).times(gasLimit), 'gwei', 'ether');
@@ -50,7 +51,6 @@ export const getFeeLevels = (coin: string, gasPrice: BigNumber | string, gasLimi
const quarter: BigNumber = gasPrice.dividedBy(4);
const high: string = gasPrice.plus(quarter.times(2)).toString();
const low: string = gasPrice.minus(quarter.times(2)).toString();
- coin = coin.toUpperCase();
return [
{
@@ -106,11 +106,11 @@ export const init = (): any => {
// TODO: check if there are some unfinished tx in localStorage
const { config } = getState().localStorage;
- const coin = config.coins.find(c => c.symbol === urlParams.coin);
+ const coin = config.coins.find(c => c.network === urlParams.coin);
const gasPrice: BigNumber = new BigNumber( EthereumjsUnits.convert(web3instance.gasPrice, 'wei', 'gwei') ) || new BigNumber(coin.defaultGasPrice);
const gasLimit: string = coin.defaultGasLimit.toString();
- const feeLevels: Array = getFeeLevels(urlParams.coin, gasPrice, gasLimit);
+ const feeLevels: Array = getFeeLevels(coin.symbol, gasPrice, gasLimit);
// TODO: get nonce
@@ -119,6 +119,7 @@ export const init = (): any => {
checksum: selected.checksum,
accountIndex: parseInt(urlParams.address),
coin: urlParams.coin,
+ coinSymbol: coin.symbol,
token: urlParams.coin,
location: location.pathname,
@@ -204,15 +205,32 @@ export const validation = (): any => {
errors.amount = 'Amount is not a number';
} else {
const account = getState().accounts.find(a => a.checksum === state.checksum && a.index === state.accountIndex && a.coin === state.coin);
+ let decimalRegExp;
+
if (state.token !== state.coin) {
- const tokenBalance: string = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === state.token).balance;
- if (new BigNumber(state.total).greaterThan(account.balance)) {
- errors.amount = `Not enough ${ state.coin.toUpperCase() } to cover transaction fee`;
- } else if (new BigNumber(state.amount).greaterThan(tokenBalance)) {
+ const token: any = getState().tokens.find(t => t.ethAddress === account.address && t.symbol === state.token);
+
+ if (parseInt(token.decimals) > 0) {
+ decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,' + token.decimals + '})?|[1-9]+\\.?([0-9]{0,' + token.decimals + '})?|\\.[0-9]{1,' + token.decimals + '})$');
+ } else {
+ // decimalRegExp = new RegExp('^(0|0\\.?|[1-9]+\\.?)$');
+ decimalRegExp = new RegExp('^[0-9]+$');
+ }
+
+ if (!state.amount.match(decimalRegExp)) {
+ errors.amount = `Maximum ${ token.decimals} decimals allowed`;
+ } else if (new BigNumber(state.total).greaterThan(account.balance)) {
+ errors.amount = `Not enough ${ state.coinSymbol.toUpperCase() } to cover transaction fee`;
+ } else if (new BigNumber(state.amount).greaterThan(token.balance)) {
errors.amount = 'Not enough funds';
+ } else if (new BigNumber(state.amount).lessThanOrEqualTo('0')) {
+ errors.amount = 'Amount is too low';
}
} else {
- if (new BigNumber(state.total).greaterThan(account.balance)) {
+ decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9]+\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$');
+ if (!state.amount.match(decimalRegExp)) {
+ errors.amount = `Maximum 18 decimals allowed`;
+ } else if (new BigNumber(state.total).greaterThan(account.balance)) {
errors.amount = 'Not enough funds';
}
}
@@ -245,7 +263,7 @@ export const validation = (): any => {
const gp: BigNumber = new BigNumber(state.gasPrice);
if (gp.greaterThan(100)) {
errors.gasPrice = 'Gas price is too high';
- } else if (gp.lessThan(1)) {
+ } else if (gp.lessThanOrEqualTo('0')) {
errors.gasPrice = 'Gas price is too low';
}
}
@@ -334,7 +352,7 @@ export const onCurrencyChange = (currency: any): any => {
}
const { config } = getState().localStorage;
- const coin = config.coins.find(c => c.symbol === currentState.coin);
+ const coin = config.coins.find(c => c.network === currentState.coin);
let gasLimit: string = '';
let amount: string = currentState.amount;
@@ -355,7 +373,7 @@ export const onCurrencyChange = (currency: any): any => {
total = calculateTotal(amount, currentState.gasPrice, currentState.gasLimit);
}
- const feeLevels: Array = getFeeLevels(currentState.coin, currentState.gasPrice, gasLimit);
+ const feeLevels: Array = getFeeLevels(currentState.coinSymbol, currentState.gasPrice, gasLimit);
const state: State = {
...currentState,
@@ -433,7 +451,7 @@ export const onFeeLevelChange = (feeLevel: any): any => {
// TODO: update value for custom fee
state.advanced = true;
feeLevel.gasPrice = state.gasPrice;
- feeLevel.label = `${ calculateFee(state.gasPrice, state.gasLimit) } ${ state.coin.toUpperCase() }`;
+ feeLevel.label = `${ calculateFee(state.gasPrice, state.gasLimit) } ${ state.coinSymbol }`;
} else {
const customLevel = state.feeLevels.find(f => f.value === 'Custom');
customLevel.label = '';
@@ -462,12 +480,14 @@ export const onFeeLevelChange = (feeLevel: any): any => {
export const updateFeeLevels = (): any => {
return (dispatch, getState): void => {
const currentState = getState().sendForm;
- const feeLevels: Array = getFeeLevels(currentState.coin, currentState.recommendedGasPrice, currentState.gasLimit);
+ const feeLevels: Array = getFeeLevels(currentState.coinSymbol, currentState.recommendedGasPrice, currentState.gasLimit);
+ const selectedFeeLevel: ?FeeLevel = feeLevels.find(f => f.value === currentState.selectedFeeLevel.value)
const state: State = {
...currentState,
feeLevels,
- selectedFeeLevel: feeLevels.find(f => f.value === currentState.selectedFeeLevel.value),
- gasPrice: currentState.recommendedGasPrice,
+ selectedFeeLevel,
+ //gasPrice: currentState.recommendedGasPrice, // TODO HERE!
+ gasPrice: selectedFeeLevel.gasPrice, // TODO HERE!
gasPriceNeedsUpdate: false,
};
@@ -507,7 +527,7 @@ export const onGasPriceChange = (gasPrice: string): any => {
if (gasPrice.match(numberRegExp) && state.gasLimit.match(numberRegExp)) {
const customLevel = currentState.feeLevels.find(f => f.value === 'Custom');
customLevel.gasPrice = gasPrice;
- customLevel.label = `${ calculateFee(gasPrice, state.gasLimit) } ${ state.coin.toUpperCase() }`;
+ customLevel.label = `${ calculateFee(gasPrice, state.gasLimit) } ${ state.coinSymbol }`;
state.selectedFeeLevel = customLevel;
@@ -547,7 +567,7 @@ export const onGasLimitChange = (gasLimit: string): any => {
if (gasLimit.match(numberRegExp) && state.gasPrice.match(numberRegExp)) {
const customLevel = currentState.feeLevels.find(f => f.value === 'Custom');
- customLevel.label = `${ calculateFee(state.gasPrice, gasLimit) } ${ state.coin.toUpperCase() }`;
+ customLevel.label = `${ calculateFee(state.gasPrice, gasLimit) } ${ state.coinSymbol }`;
state.selectedFeeLevel = customLevel;
@@ -640,9 +660,6 @@ export const onSend = (): any => {
v: ''
}
- //const nonce = await getNonce(web3, currentAddress.address);
- //txData.nonce = web3.toHex(nonce);
-
// const gasOptions = {
// to: txData.to,
@@ -660,6 +677,7 @@ export const onSend = (): any => {
// console.log("---->GASSS", txData, gasLimit, gasPrice, EthereumjsUnits.convert(gasPrice, 'gwei', 'wei'));
const selected = findSelectedDevice(getState().connect);
+ if (!selected) return;
let signedTransaction = await TrezorConnect.ethereumSignTransaction({
device: {
@@ -697,8 +715,11 @@ export const onSend = (): any => {
txData.s = '0x' + signedTransaction.data.s;
txData.v = web3.toHex(signedTransaction.data.v);
- const gasLimit2 = await estimateGas(web3, txData);
- console.log("---->GASSS", txData, gasLimit2.toString() );
+ // const gasLimit2 = await estimateGas(web3, txData);
+ // console.log("---->GASSS", txData, gasLimit2.toString() );
+
+ const { config } = getState().localStorage;
+ const selectedCoin = config.coins.find(c => c.network === state.coin);
try {
const tx = new EthereumjsTx(txData);
@@ -708,6 +729,8 @@ export const onSend = (): any => {
dispatch({
type: SEND.TX_COMPLETE,
address: account,
+ token: state.token,
+ amount: state.amount,
txid,
txData,
});
@@ -717,7 +740,7 @@ export const onSend = (): any => {
payload: {
type: 'success',
title: 'Transaction success',
- message: `detail`,
+ message: `See transaction detail`,
cancelable: true,
actions: []
}
@@ -736,23 +759,5 @@ export const onSend = (): any => {
}
});
}
-
- // const tx = new EthereumjsTx(txData);
- // console.log("2222", tx, tx.toJSON(), tx.from, tx.to);
- // const serializedTx = '0x' + tx.serialize().toString('hex');
-
- // console.log("----> PUSZ TX", web3, currentAddress, serializedTx)
- // const txid = await pushTx(web3, serializedTx);
- // console.log("----> PUSZ TX2", web3, serializedTx)
-
- // dispatch({
- // type: SEND.TX_COMPLETE,
- // address: currentAddress,
- // txid,
- // txData,
- // })
-
- // const [ url ] = getState().router.location.pathname.split('/send');
- // dispatch( push(url) );
}
}
diff --git a/src/js/actions/SummaryActions.js b/src/js/actions/SummaryActions.js
index 6a2ad931..b9c0f492 100644
--- a/src/js/actions/SummaryActions.js
+++ b/src/js/actions/SummaryActions.js
@@ -106,11 +106,12 @@ export const onDetailsToggle = (): any => {
-export const loadTokens = (input: string): any => {
+export const loadTokens = (input: string, account: any): any => {
return async (dispatch, getState): Promise => {
if (input.length < 1) return null;
+ // TODO (eth tokens, etc tokens, ropsten tokens ...)
const { ethTokens } = getState().localStorage;
const value = input.toLowerCase();
@@ -121,18 +122,14 @@ export const loadTokens = (input: string): any => {
);
//const result = ethTokens.filter(t => t.symbol.toLowerCase().indexOf(lower) >= 0);
- console.log("RESULT!", result.length, result)
-
if (result.length > 0) {
return { options: result };
} else {
- const web3instance = getState().web3.find(w3 => w3.coin === 'eth');
+ const web3instance = getState().web3.find(w3 => w3.coin === account.coin);
const info = await getTokenInfoAsync(web3instance.erc20, input);
info.address = input;
- console.log("FETCH", info)
-
if (info) {
return {
options: [ info ]
@@ -143,13 +140,9 @@ export const loadTokens = (input: string): any => {
}
}
-
//await resolveAfter(300000);
//await resolveAfter(3000);
-
-
-
}
}
@@ -158,10 +151,7 @@ export const loadTokens = (input: string): any => {
export const selectToken = (token: any, account: any): any => {
return async (dispatch, getState): Promise => {
- console.warn("ADD", token, account)
-
const web3instance = getState().web3.find(w3 => w3.coin === account.coin);
-
dispatch({
type: TOKEN.ADD,
payload: {
@@ -171,7 +161,6 @@ export const selectToken = (token: any, account: any): any => {
}
});
- // TODO: load token balance
const tokenBalance = await getTokenBalanceAsync(web3instance.erc20, token.address, account.address);
dispatch({
type: TOKEN.SET_BALANCE,
@@ -185,6 +174,13 @@ export const selectToken = (token: any, account: any): any => {
}
}
+export const removeToken = (token: any): any => {
+ return {
+ type: TOKEN.REMOVE,
+ token
+ }
+}
+
export const onTokenSearch = (search: string): any => {
diff --git a/src/js/actions/TrezorConnectActions.js b/src/js/actions/TrezorConnectActions.js
index d12f2a7f..a725f742 100644
--- a/src/js/actions/TrezorConnectActions.js
+++ b/src/js/actions/TrezorConnectActions.js
@@ -19,7 +19,7 @@ import { getTransactionHistory } from '../services/EtherscanService';
import { push } from 'react-router-redux';
-import { init as initWeb3, getNonce, getBalanceAsync, getTokenBalanceAsync } from './Web3Actions';
+import { init as initWeb3, getNonceAsync, getBalanceAsync, getTokenBalanceAsync } from './Web3Actions';
import type { Discovery } from '../reducers/DiscoveryReducer';
import { resolveAfter } from '../utils/promiseUtils';
@@ -53,6 +53,10 @@ export const init = (): any => {
try {
await TrezorConnect.init({
transport_reconnect: true,
+ coins_src: './data/coins.json',
+ firmware_releases_src: './data/releases-1.json',
+ transport_config_src: './data/config_signed.bin',
+ latest_bridge_src: './data/latest.txt'
});
setTimeout(() => {
@@ -116,12 +120,19 @@ export const postInit = (): any => {
export const initConnectedDevice = (device: any): any => {
return (dispatch, getState): void => {
+ //dispatch( onSelectDevice(device) );
+
const selected = findSelectedDevice(getState().connect);
- if (device.unacquired && selected && selected.path !== device.path && !selected.connected) {
+ if (selected && selected.checksum) {
dispatch( onSelectDevice(device) );
} else if (!selected) {
dispatch( onSelectDevice(device) );
}
+ // if (device.unacquired && selected && selected.path !== device.path && !selected.connected) {
+ // dispatch( onSelectDevice(device) );
+ // } else if (!selected) {
+ // dispatch( onSelectDevice(device) );
+ // }
}
}
@@ -235,47 +246,27 @@ export const getSelectedDeviceState = (): any => {
export const deviceDisconnect = (device: any): any => {
return async (dispatch, getState): Promise => {
- if (!device || !device.features) return null;
-
const selected = findSelectedDevice(getState().connect);
- if (selected && selected.features.device_id === device.features.device_id) {
- stopDiscoveryProcess(selected);
- }
-
- const affected = getState().connect.devices.filter(d => d.features && d.checksum && !d.remember && d.features.device_id === device.features.device_id);
- if (affected.length > 0) {
- dispatch({
- type: CONNECT.REMEMBER_REQUEST,
- device,
- allInstances: affected
- });
- }
-
-
- // if (selected && selected.checksum) {
- // if (device.features && device.features.device_id === selected.features.device_id) {
- // stopDiscoveryProcess(selected);
- // }
- // }
-
-
- // // stop running discovery process on this device
- // if (selected && selected.path === device.path){
- // if (selected.checksum) {
- // stopDiscoveryProcess(selected);
- // }
- // }
+ if (device && device.features) {
+ if (selected && selected.features.device_id === device.features.device_id) {
+ stopDiscoveryProcess(selected);
+ }
- // // check if disconnected device was remembered before.
- // // request modal if not
- // const affected = getState().connect.devices.filter(d => d.path === device.path && d.checksum && !device.remember);
-
+ const affected = getState().connect.devices.filter(d => d.features && d.checksum && !d.remember && d.features.device_id === device.features.device_id);
+ if (affected.length > 0) {
+ dispatch({
+ type: CONNECT.REMEMBER_REQUEST,
+ device,
+ allInstances: affected
+ });
+ }
+ }
- // check if reload is needed
if (!selected) {
dispatch( switchToFirstAvailableDevice() );
}
+
}
}
@@ -397,7 +388,7 @@ export const beginDiscoveryProcess = (device: any, coin: string): any => {
return async (dispatch, getState) => {
const { config } = getState().localStorage;
- const coinToDiscover = config.coins.find(c => c.symbol === coin);
+ const coinToDiscover = config.coins.find(c => c.network === coin);
// TODO: validate device checksum
// const checksum = await __acquire(device.path, device.instance);
@@ -455,7 +446,7 @@ export const beginDiscoveryProcess = (device: any, coin: string): any => {
// send data to reducer
dispatch({
type: DISCOVERY.START,
- coin: coinToDiscover.shortcut,
+ coin: coinToDiscover.network,
device,
xpub: response.data.publicKey,
basePath,
@@ -574,7 +565,7 @@ export const discoverAddress = (device: any, discoveryProcess: Discovery): any =
})
}
- const nonce = await getNonce(web3instance.web3, ethAddress);
+ const nonce = await getNonceAsync(web3instance.web3, ethAddress);
if (discoveryProcess.interrupted) return;
dispatch({
type: ADDRESS.SET_NONCE,
diff --git a/src/js/actions/Web3Actions.js b/src/js/actions/Web3Actions.js
index dd98876f..3efb1833 100644
--- a/src/js/actions/Web3Actions.js
+++ b/src/js/actions/Web3Actions.js
@@ -15,6 +15,41 @@ import { httpRequest } from '../utils/networkUtils';
type ActionMethod = (dispatch: any, getState: any) => Promise;
+type Web3Payload =
+| {
+ name: string;
+ instance: Web3;
+ chainId: number;
+ erc20abi: any;
+}
+| {
+ network: string;
+ blockHash: string;
+}
+| {
+ network: string;
+ gasPrice: string;
+}
+| {
+ network: string;
+ address: string;
+ balance: string;
+}
+| {
+ network: string;
+ address: string;
+ nonce: string;
+}
+| {
+ network: string;
+ blockHash: string;
+};
+
+type Web3Action = {
+ type: string,
+ payload?: Web3Payload
+};
+
export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
return async (dispatch, getState) => {
@@ -30,7 +65,7 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
return;
}
- const coinName = coin.shortcut;
+ const coinName = coin.network;
const urls = coin.backends[0].urls;
let web3host: string = urls[0];
@@ -106,36 +141,42 @@ export function init(web3: ?Web3, coinIndex: number = 0): ActionMethod {
//const shh = instance.shh.newIdentity();
const latestBlockFilter = instance.eth.filter('latest');
- latestBlockFilter.watch(async (error, blockHash) => {
+ const onBlockMined = async (error, blockHash) => {
if (error) {
- console.warn("ERROR!", error);
- // setInterval(() => {
- // dispatch( getGasPrice(coinName) );
- // }, 5000);
+ window.setTimeout(() => {
+ // try again
+ onBlockMined("manually_triggered_error", undefined);
+ }, 30000);
+ }
+
+ if (blockHash) {
+ dispatch({
+ type: WEB3.BLOCK_UPDATED,
+ name: coinName,
+ blockHash
+ });
}
-
- dispatch({
- type: WEB3.BLOCK_UPDATED,
- name: coinName,
- blockHash
- });
// TODO: filter only current device
const accounts = getState().accounts.filter(a => a.coin === coinName);
for (const addr of accounts) {
dispatch( getBalance(addr) );
+ dispatch( getNonce(addr) );
}
dispatch( getGasPrice(coinName) );
- // if (pendingTxs.length > 0) {
- // for (const tx of pendingTxs) {
- // dispatch( getTransactionReceipt(tx) );
- // }
- // }
- });
+ const pending = getState().pending.filter(p => p.coin === coinName);
+ for (const tx of pending) {
+ dispatch( getTransactionReceipt(tx) );
+ }
+
+ }
+
+ latestBlockFilter.watch(onBlockMined);
+
// init next coin
dispatch( init(instance, coinIndex + 1) );
@@ -238,18 +279,46 @@ export function getBalance(addr: Address): ActionMethod {
}
}
-export function getTransactionReceipt(txid: string): any {
+export function getNonce(addr: Address) {
+
return async (dispatch, getState) => {
- const { web3 } = getState().web3;
+
+ const web3instance = getState().web3.filter(w3 => w3.coin === addr.coin)[0];
+ const web3 = web3instance.web3;
+
+ web3.eth.getTransactionCount(addr.address, (error, result) => {
+ if (!error) {
+ if (addr.nonce !== result) {
+ dispatch({
+ type: ADDRESS.SET_NONCE,
+ address: addr.address,
+ nonce: result
+ });
+ }
+
+
+ }
+ });
+ }
+}
+
+export function getTransactionReceipt(tx: any): any {
+ return async (dispatch, getState) => {
+
+ const web3instance = getState().web3.filter(w3 => w3.coin === tx.coin)[0];
+ const web3 = web3instance.web3;
+
//web3.eth.getTransactionReceipt(txid, (error, tx) => {
- web3.eth.getTransaction(txid, (error, tx) => {
- if (tx && tx.blockNumber) {
- web3.eth.getBlock(tx.blockHash, (error, block) => {
- console.log("---MAMM BLOCK", error, block, tx, tx.blockHash)
+ web3.eth.getTransaction(tx.id, (error, receipt) => {
+ console.log("RECEIP", receipt)
+ if (receipt && receipt.blockNumber) {
+ web3.eth.getBlock(receipt.blockHash, (error, block) => {
+ console.log("---MAMM BLOCK", error, block, receipt, receipt.blockHash)
dispatch({
- type: ACTIONS.TX_CONFIRMED,
- txid,
+ //type: ACTIONS.TX_CONFIRMED,
+ type: WEB3.PENDING_TX_RESOLVED,
tx,
+ receipt,
block
})
});
@@ -306,7 +375,7 @@ export const getTokenBalanceAsync = (erc20: any, token: any, address: any): Prom
});
}
-export function getNonce(web3, address) {
+export function getNonceAsync(web3, address) {
return new Promise((resolve, reject) => {
web3.eth.getTransactionCount(address, (error, result) => {
if (error) {
@@ -389,81 +458,6 @@ export function pushTx(web3, tx) {
})
}
-export function composeTransaction() {
- return async function (dispatch, getState) {
- const { web3 } = getState().web3;
- const { address, amount } = getState().sendForm;
-
- const resp = await TrezorConnect.getPublicKey({ path: "m/44'/60'/0'/0", confirmation: false });
-
- const hdk = new HDKey();
- hdk.publicKey = new Buffer(resp.data.publicKey, 'hex');
- hdk.chainCode = new Buffer(resp.data.chainCode, 'hex');
-
- const derivedKey = hdk.derive("m/0");
- const myAddress = EthereumjsUtil.publicToAddress(derivedKey.publicKey, true);
-
- const txData = {
- address_n: [
- (44 | 0x80000000) >>> 0,
- (60 | 0x80000000) >>> 0,
- (0 | 0x80000000) >>> 0,
- 0, 0
- ],
- to: address,
- value: web3.toHex(web3.toWei(amount, 'ether')),
- data,
- chainId: 3
- }
-
- console.log("NONCE", myAddress)
- const nonce = await getNonce(web3, '0x' + myAddress.toString('hex') );
- console.log("NONCE", nonce)
-
- const gasOptions = {
- to: txData.to,
- data: txData.data
- }
- const gasLimit = await estimateGas(web3, gasOptions);
- const gasPrice = await getGasPrice(web3);
-
- txData.nonce = web3.toHex(nonce);
- txData.gasLimit = web3.toHex(gasLimit);
- txData.gasPrice = web3.toHex(gasPrice);
-
- console.log("NONCE", nonce, gasLimit, gasPrice)
-
- let signedTransaction = await TrezorConnect.ethereumSignTransaction({
- //path: "m/44'/60'/0'/0/0",
- address_n: txData.address_n,
- nonce: strip(txData.nonce),
- gas_price: strip(txData.gasPrice),
- gas_limit: strip(txData.gasLimit),
- to: strip(txData.to),
- value: strip(txData.value),
- data: txData.data,
- chain_id: txData.chainId
- });
-
- txData.r = '0x' + signedTransaction.data.r;
- txData.s = '0x' + signedTransaction.data.s;
- txData.v = web3.toHex(signedTransaction.data.v);
-
- const tx = new EthereumjsTx(txData);
- const serializedTx = '0x' + tx.serialize().toString('hex');
-
- const txid = await pushTx(web3, serializedTx);
-
- dispatch({
- type: 'tx_complete',
- txid
- })
-
- console.log("TXID", txid);
- }
-}
-
-
diff --git a/src/js/actions/constants/Web3.js b/src/js/actions/constants/Web3.js
index 6334e1a0..f1e3eee8 100644
--- a/src/js/actions/constants/Web3.js
+++ b/src/js/actions/constants/Web3.js
@@ -6,4 +6,5 @@ export const STOP: string = 'web3__stop';
export const CREATE: string = 'web3__create';
export const READY: string = 'web3__ready';
export const BLOCK_UPDATED: string = 'web3__block_updated';
-export const GAS_PRICE_UPDATED: string = 'web3__gas_price_updated';
\ No newline at end of file
+export const GAS_PRICE_UPDATED: string = 'web3__gas_price_updated';
+export const PENDING_TX_RESOLVED: string = 'web3__pending_tx_resolved';
\ No newline at end of file
diff --git a/src/js/actions/index.js b/src/js/actions/index.js
index 45a72ee2..c0e59632 100644
--- a/src/js/actions/index.js
+++ b/src/js/actions/index.js
@@ -15,7 +15,6 @@ export const ON_GAS_PRICE_CHANGE: string = 'send__on_gas_price_change';
export const ON_GAS_LIMIT_CHANGE: string = 'send__on_gas_limit_change';
export const ON_TX_DATA_CHANGE: string = 'send__on_data_change';
export const ON_TX_SEND: string = 'send__on_send';
-export const ON_TX_COMPLETE: string = 'send__on_tx_complete';
export const ON_GAS_PRICE_UPDATE: string = 'send__on_gas_price_update';
diff --git a/src/js/components/common/Footer.js b/src/js/components/common/Footer.js
index d69f8dc7..552d68f3 100644
--- a/src/js/components/common/Footer.js
+++ b/src/js/components/common/Footer.js
@@ -2,16 +2,31 @@
'use strict';
import React from 'react';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+
+import * as LogActions from '../../actions/LogActions';
const Footer = (props: any): any => {
return (
);
}
-export default Footer;
+export default connect(
+ (state) => {
+ return {
+
+ }
+ },
+ (dispatch) => {
+ return {
+ toggle: bindActionCreators(LogActions.toggle, dispatch),
+ };
+ }
+)(Footer);
diff --git a/src/js/components/common/Header.js b/src/js/components/common/Header.js
index 7ffe5b0b..9e8295d9 100644
--- a/src/js/components/common/Header.js
+++ b/src/js/components/common/Header.js
@@ -8,9 +8,26 @@ export default class Header extends Component {
return (
);
}
}
+
+
+
diff --git a/src/js/components/common/Log.js b/src/js/components/common/Log.js
index 62ac4e18..40aaedc8 100644
--- a/src/js/components/common/Log.js
+++ b/src/js/components/common/Log.js
@@ -5,36 +5,32 @@ import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
-import * as SendFormActions from '../../actions/SendFormActions';
-import { getAddress } from '../../actions/TrezorConnectActions';
-
+import * as LogActions from '../../actions/LogActions';
const Log = (props: any) => {
- return (
-
- Log
-
- )
-}
-function mapStateToProps(state, own) {
-
-}
-
-function mapDispatchToProps(dispatch) {
+ if (!props.log.opened)
+ return null;
+ return (
+
+
+
Log
+
Attention: The log contains your XPUBs. Anyone with your XPUBs can see your account history.
+
+
+ )
}
export default connect(
(state) => {
return {
- accounts: state.accounts,
- receive: state.receive
+ log: state.log
};
},
(dispatch) => {
return {
- getAddress: bindActionCreators(getAddress, dispatch),
+ toggle: bindActionCreators(LogActions.toggle, dispatch),
};
}
)(Log);
\ No newline at end of file
diff --git a/src/js/components/landing/ConnectDevice.js b/src/js/components/landing/ConnectDevice.js
index 32f25e01..f5dcb671 100644
--- a/src/js/components/landing/ConnectDevice.js
+++ b/src/js/components/landing/ConnectDevice.js
@@ -25,10 +25,10 @@ export default (props: any): any => {
Connect TREZOR to continue
- {/* Don't have TREZOR? Get one
*/}
+ {/* Don't have TREZOR? Get one
*/}
- Don't have TREZOR? Get one
+ Don't have TREZOR? Get one
diff --git a/src/js/components/landing/LandingPage.js b/src/js/components/landing/LandingPage.js
index 440ba3f8..e38cb86f 100644
--- a/src/js/components/landing/LandingPage.js
+++ b/src/js/components/landing/LandingPage.js
@@ -8,6 +8,7 @@ import LocalStorageError from './LocalStorageError';
import TrezorConnectError from './TrezorConnectError';
import Header from '../common/Header';
import Footer from '../common/Footer';
+import Log from '../common/Log';
import { Notification } from '../common/Notification';
export default (props: any): any => {
@@ -40,6 +41,7 @@ export default (props: any): any => {
{ notification }
+
The private bank in your hands.
TREZOR Wallet is an easy-to-use interface for your TREZOR.
@@ -59,10 +61,11 @@ export default (props: any): any => {
{/* */}
- {/* Don't have TREZOR? Get one
*/}
+ {/* Don't have TREZOR? Get one
*/}
+
+
-
- Don't have TREZOR? Get one
diff --git a/src/js/components/modal/ConfirmAddress.js b/src/js/components/modal/ConfirmAddress.js
index 7af6ddf3..5cfcd888 100644
--- a/src/js/components/modal/ConfirmAddress.js
+++ b/src/js/components/modal/ConfirmAddress.js
@@ -7,6 +7,8 @@ import { findSelectedDevice } from '../../reducers/TrezorConnectReducer';
const ConfirmAddress = (props: any): any => {
const account = props.accounts.find(a => a.checksum === props.receive.checksum && a.index === props.receive.accountIndex && a.coin === props.receive.coin);
+ const { config } = props.localStorage;
+ const selectedCoin = config.coins.find(c => c.network === account.coin);
return (
@@ -16,7 +18,7 @@ const ConfirmAddress = (props: any): any => {
{ account.address }
-
+
);
diff --git a/src/js/components/modal/ConfirmSignTx.js b/src/js/components/modal/ConfirmSignTx.js
index 1fa9621a..9983e6dc 100644
--- a/src/js/components/modal/ConfirmSignTx.js
+++ b/src/js/components/modal/ConfirmSignTx.js
@@ -8,6 +8,7 @@ const Confirmation = (props): any => {
amount,
address,
coin,
+ coinSymbol,
token,
total,
selectedFeeLevel
@@ -21,7 +22,7 @@ const Confirmation = (props): any => {
-
{ `${amount} ${token.toUpperCase() }` }
+
{ `${amount} ${ coinSymbol }` }
{ address }
diff --git a/src/js/components/modal/ModalContainer.js b/src/js/components/modal/ModalContainer.js
index ce1266cd..d45496a7 100644
--- a/src/js/components/modal/ModalContainer.js
+++ b/src/js/components/modal/ModalContainer.js
@@ -103,6 +103,7 @@ const mapStateToProps = (state: any, own: any): any => {
devices: state.connect.devices,
sendForm: state.sendForm,
receive: state.receive,
+ localStorage: state.localStorage
};
}
diff --git a/src/js/components/modal/Passphrase.js b/src/js/components/modal/Passphrase.js
index dde75b65..2dc09546 100644
--- a/src/js/components/modal/Passphrase.js
+++ b/src/js/components/modal/Passphrase.js
@@ -24,7 +24,7 @@ export default class PinModal extends Component {
constructor(props: any) {
super(props);
- console.warn("PROPZ", props)
+ // check if this device is already known
const isSavedDevice = props.devices.find(d => d.path === props.modal.device.path && d.remember);
this.state = {
diff --git a/src/js/components/modal/Pin.js b/src/js/components/modal/Pin.js
index 782c988f..3917619f 100644
--- a/src/js/components/modal/Pin.js
+++ b/src/js/components/modal/Pin.js
@@ -133,8 +133,8 @@ export default class Pin extends Component {
-
- Not sure how PIN works? Learn more
+
+ Not sure how PIN works? Learn more
);
}
diff --git a/src/js/components/wallet/Acquire.js b/src/js/components/wallet/Acquire.js
index bf8ff741..bb316f1f 100644
--- a/src/js/components/wallet/Acquire.js
+++ b/src/js/components/wallet/Acquire.js
@@ -2,17 +2,36 @@
'use strict';
import React from 'react';
+import { Notification } from '../common/Notification';
const Acquire = (props: any): any => {
+
+ const actions = [
+ {
+ label: 'Acquire device',
+ callback: () => {
+ props.acquireDevice()
+ }
+ }
+ ];
+
return (
-
+
{} }
+ />
+ {/*
-
Device is used in other window
-
Do you want to use your device in this window?
+
+
-
+ */}
);
}
diff --git a/src/js/components/wallet/History.js b/src/js/components/wallet/History.js
index 45f7ebe4..187e1849 100644
--- a/src/js/components/wallet/History.js
+++ b/src/js/components/wallet/History.js
@@ -38,7 +38,7 @@ const History = (props): any => {
return (
diff --git a/src/js/components/wallet/account/AbstractAccount.js b/src/js/components/wallet/account/AbstractAccount.js
index 9ad898ee..eb79f35e 100644
--- a/src/js/components/wallet/account/AbstractAccount.js
+++ b/src/js/components/wallet/account/AbstractAccount.js
@@ -14,25 +14,6 @@ export default class AbstractAccount extends Component {
this.props.updateAccount();
}
- // shouldInitAccount(newProps: any): boolean {
- // const locationChanged: boolean = newProps.location.pathname !== this.props.location.pathname;
- // const accountNotLoaded: boolean = !newProps.detail.loaded && !this.props.detail.loaded;
- // return (locationChanged || accountNotLoaded);
- // }
-
- // shouldUpdateAccount(newProps: any): boolean {
- // const { detail } = this.props;
- // const loaded: boolean = detail.loaded;
-
- // if (detail.address === '') {
- // const currentAccount = this.props.accounts.find(a => a.index === detail.addressIndex && a.coin === detail.coin && a.checksum === detail.checksum);
-
- // }
-
-
- // // return (loaded && );
- // }
-
componentWillUnmount() {
this.props.disposeAccount();
}
diff --git a/src/js/components/wallet/account/AccountTabs.js b/src/js/components/wallet/account/AccountTabs.js
index 34f4c086..a4a8d41a 100644
--- a/src/js/components/wallet/account/AccountTabs.js
+++ b/src/js/components/wallet/account/AccountTabs.js
@@ -1,9 +1,62 @@
/* @flow */
'use strict';
-import React from 'react';
+import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
+type State = {
+ style: any;
+
+}
+
+class Indicator extends Component {
+
+ state: State;
+
+ constructor(props: any) {
+ super(props);
+
+ this.state = {
+ style: {
+ width: 0,
+ left: 0
+ },
+ }
+ }
+
+ componentDidMount() {
+ this.reposition();
+ }
+
+ componentDidUpdate(newProps: any) {
+ this.reposition();
+ }
+
+ reposition() {
+ const tabs = document.querySelector('.account-tabs');
+ const active = tabs.querySelector('.active');
+ const bounds = active.getBoundingClientRect();
+
+ const left = bounds.left - tabs.getBoundingClientRect().left;
+
+ if (this.state.style.left !== left) {
+ this.setState({
+ style: {
+ width: bounds.width,
+ left: left,
+ }
+ })
+ }
+
+ }
+
+ render() {
+ return (
+ { this.props.pathname }
+ );
+ }
+}
+
const AccountTabs = (props: any): any => {
const urlParams = props.match.params;
@@ -24,9 +77,10 @@ const AccountTabs = (props: any): any => {
Receive
-
+ {/*
Sign & Verify
-
+ */}
+
);
}
diff --git a/src/js/components/wallet/aside/AccountSelection.js b/src/js/components/wallet/aside/AccountSelection.js
index 8a8bc53e..dde3e897 100644
--- a/src/js/components/wallet/aside/AccountSelection.js
+++ b/src/js/components/wallet/aside/AccountSelection.js
@@ -8,6 +8,8 @@ import BigNumber from 'bignumber.js';
import { getAccounts } from '../../../utils/reducerUtils';
import { findSelectedDevice } from '../../../reducers/TrezorConnectReducer';
import Loader from '../../common/LoaderCircle';
+import Tooltip from 'rc-tooltip';
+
const AccountSelection = (props: any): any => {
@@ -17,7 +19,11 @@ const AccountSelection = (props: any): any => {
const { location } = props.router;
const accounts = props.accounts;
const baseUrl: string = `/device/${location.params.device}`;
- const fiatRate = props.fiatRate || '1';
+
+ const { config } = props.localStorage;
+ const selectedCoin = config.coins.find(c => c.network === location.params.coin);
+
+ const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
// console.warn("AccountSelectionRender", selected, props);
@@ -25,9 +31,18 @@ const AccountSelection = (props: any): any => {
let selectedAccounts = deviceAddresses.map((address, i) => {
// const url: string = `${baseUrl}/coin/${location.params.coin}/address/${i}`;
const url: string = location.pathname.replace(/address+\/([0-9]*)/, `address/${i}`);
- const b = new BigNumber(address.balance);
- const fiat = b.times(fiatRate).toFixed(2);
- const balance = address.balance !== '' ? `${ address.balance } ${ location.params.coin.toUpperCase() } / $${ fiat }` : 'Loading...';
+
+ let balance: string = 'Loading...';
+ if (address.balance !== '') {
+ if (fiatRate) {
+ const accountBalance = new BigNumber(address.balance);
+ const fiat = accountBalance.times(fiatRate.value).toFixed(2);
+ balance = `${ address.balance } ${ selectedCoin.symbol } / $${ fiat }`;
+ } else {
+ balance = `${ address.balance } ${ selectedCoin.symbol }`;
+ }
+ }
+
return (
{ `Address #${(address.index + 1 )}` }
@@ -54,34 +69,54 @@ const AccountSelection = (props: any): any => {
if (discovery) {
if (discovery.completed) {
// TODO: add only if last one is not empty
- discoveryStatus = (
-
- Add address
-
- )
+ //if (selectedAccounts.length > 0 && selectedAccounts[selectedAccounts.length - 1])
+ const lastAccount = deviceAddresses[deviceAddresses.length - 1];
+ if (lastAccount && new BigNumber(lastAccount.balance).greaterThan(0) || lastAccount.nonce > 0) {
+ discoveryStatus = (
+
+ Add address
+
+ );
+ } else {
+ const tooltip = (
+
+ To add a new address, last address must have some transactions.
+
+ )
+ discoveryStatus = (
+ }
+ overlay={ tooltip }
+ placement="top">
+
+ Add address
+
+
+ );
+ }
+
} else if (!selected.connected) {
discoveryStatus = (
Addresses could not be loaded
{ `Connect ${ selected.instanceLabel } device` }
- )
+ );
} else {
discoveryStatus = (
Loading accounts...
- )
+ );
}
}
- const { config } = props.localStorage;
- const selectedCoin = config.coins.find(c => c.shortcut === location.params.coin);
+
let backButton = null;
if (selectedCoin) {
backButton = (
-
- { selectedCoin.name }
+
+ { selectedCoin.name }
);
}
@@ -89,7 +124,9 @@ const AccountSelection = (props: any): any => {
return (
{ backButton }
- { selectedAccounts }
+
+ { selectedAccounts }
+
{ discoveryStatus }
);
diff --git a/src/js/components/wallet/aside/Aside.js b/src/js/components/wallet/aside/Aside.js
index 52df1446..f1a672f3 100644
--- a/src/js/components/wallet/aside/Aside.js
+++ b/src/js/components/wallet/aside/Aside.js
@@ -41,7 +41,7 @@ const Aside = (props: any): any => {
// return (
//
@@ -66,14 +66,12 @@ const Aside = (props: any): any => {
);
}
- console.warn("ASIDEE", props)
-
return (
{ menu }
)
diff --git a/src/js/components/wallet/aside/CoinSelection.js b/src/js/components/wallet/aside/CoinSelection.js
index a28692a4..9f06d5ee 100644
--- a/src/js/components/wallet/aside/CoinSelection.js
+++ b/src/js/components/wallet/aside/CoinSelection.js
@@ -9,10 +9,10 @@ const CoinSelection = (props: any): any => {
const { config } = props.localStorage;
const walletCoins = config.coins.map(item => {
- const url = `${ location.pathname }/coin/${ item.shortcut }/address/0`;
- const className = `coin ${ item.shortcut }`
+ const url = `${ location.pathname }/coin/${ item.network }/address/0`;
+ const className = `coin ${ item.network }`
return (
-
+
{ item.name }
)
diff --git a/src/js/components/wallet/aside/DeviceSelection.js b/src/js/components/wallet/aside/DeviceSelection.js
index 35efd0d9..9aba5769 100644
--- a/src/js/components/wallet/aside/DeviceSelection.js
+++ b/src/js/components/wallet/aside/DeviceSelection.js
@@ -70,7 +70,9 @@ const Value = (props: any): any => {
{ device.instanceLabel }
{ deviceStatus }
- { deviceMenu }
+
+ { deviceMenuButtons }
+
);
}
diff --git a/src/js/components/wallet/send/AdvancedForm.js b/src/js/components/wallet/send/AdvancedForm.js
index 4408b344..bba400c4 100644
--- a/src/js/components/wallet/send/AdvancedForm.js
+++ b/src/js/components/wallet/send/AdvancedForm.js
@@ -46,7 +46,7 @@ const AdvancedForm = (props: any): any => {
Gas Price is the amount you pay per unit of gas.
TX fee = gas price * gas limit & is paid to miners for including your TX in a block.
Higher the gas price = faster transaction, but more expensive. Default is { gasPrice } GWEI.
- Read more
+ Read more
);
@@ -123,8 +123,6 @@ const AdvancedForm = (props: any): any => {
{ props.children }
-
-
)
}
diff --git a/src/js/components/wallet/send/PendingTransactions.js b/src/js/components/wallet/send/PendingTransactions.js
index e69de29b..1cc7c3d3 100644
--- a/src/js/components/wallet/send/PendingTransactions.js
+++ b/src/js/components/wallet/send/PendingTransactions.js
@@ -0,0 +1,67 @@
+/* @flow */
+'use strict';
+
+import React from 'react';
+import ColorHash from 'color-hash';
+import ScaleText from 'react-scale-text';
+
+const PendingTransactions = (props: any): any => {
+
+ const account = props.accounts.find(a => a.checksum === props.sendForm.checksum && a.index === props.sendForm.accountIndex && a.coin === props.sendForm.coin);
+ const pending = props.pending.filter(p => p.coin === account.coin && p.address === account.address);
+
+ if (pending.length < 1) return null;
+
+ const tokens = props.tokens.filter(t => t.ethAddress === account.address);
+
+ const bgColor = new ColorHash({lightness: 0.7});
+ const textColor = new ColorHash();
+
+ const pendings = pending.map((tx, i) => {
+
+ let iconColor, symbol, name;
+
+ if (tx.token !== tx.coin) {
+ const token = tokens.find(t => t.symbol === tx.token);
+ iconColor = {
+ color: textColor.hex(token.name),
+ background: bgColor.hex(token.name),
+ borderColor: bgColor.hex(token.name)
+ }
+ symbol = token.symbol.toUpperCase();
+ name = token.name;
+ } else {
+ iconColor = {
+ color: textColor.hex(tx.coin),
+ background: bgColor.hex(tx.coin),
+ borderColor: bgColor.hex(tx.coin)
+ }
+ symbol = props.selectedCoin.symbol;
+ name = props.selectedCoin.name;
+ }
+
+ return (
+
+
+
+
{ tx.amount } { symbol }
+
+ )
+ });
+
+
+ return (
+
+
Pending transactions
+ { pendings }
+
+ )
+}
+
+export default PendingTransactions;
\ No newline at end of file
diff --git a/src/js/components/wallet/send/SendForm.js b/src/js/components/wallet/send/SendForm.js
index 7527344f..8cc4d591 100644
--- a/src/js/components/wallet/send/SendForm.js
+++ b/src/js/components/wallet/send/SendForm.js
@@ -4,6 +4,7 @@
import React, { Component } from 'react';
import Select from 'react-select';
import AdvancedForm from './AdvancedForm';
+import PendingTransactions from './PendingTransactions';
import { FeeSelectValue, FeeSelectOption } from './FeeSelect';
import { Notification } from '../../common/Notification';
import AbstractAccount from '../account/AbstractAccount';
@@ -27,6 +28,7 @@ const _render = (props: any): any => {
amount,
setMax,
coin,
+ coinSymbol,
token,
feeLevels,
fee,
@@ -38,7 +40,6 @@ const _render = (props: any): any => {
infos,
advanced,
sending,
- sendingStatus
} = props.sendForm;
const {
@@ -51,11 +52,14 @@ const _render = (props: any): any => {
onSend,
} = props.sendFormActions;
- //const addressTokens = props.tokens.filter(t => t.ethAddress === currentAccount.address);
+ const { config } = props.localStorage;
+ const selectedCoin = config.coins.find(c => c.network === coin);
+ const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
+
const tokens = addressTokens.map(t => {
return { value: t.symbol, label: t.symbol };
});
- tokens.unshift({ value: coin, label: coin.toUpperCase() });
+ tokens.unshift({ value: selectedCoin.network, label: selectedCoin.symbol });
const setMaxClassName: string = setMax ? 'set-max enabled' : 'set-max';
@@ -75,12 +79,12 @@ const _render = (props: any): any => {
addressClassName = 'valid';
}
- let buttonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || address.length === 0 || sending;
+ let buttonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || amount.length === 0 || address.length === 0 || sending;
let buttonLabel: string = 'Send';
if (coin !== token && amount.length > 0 && !errors.amount) {
buttonLabel += ` ${amount} ${ token.toUpperCase() }`
} else if (coin === token && total !== '0') {
- buttonLabel += ` ${total} ${ token.toUpperCase() }`;
+ buttonLabel += ` ${total} ${ selectedCoin.symbol }`;
}
//const device = props.devices.find(d => d.checksum === currentAccount.checksum);
@@ -90,13 +94,6 @@ const _render = (props: any): any => {
}
let notification = null;
- // if (sendingStatus) {
- // if (sendingStatus.success) {
- // notification = ();
- // } else {
- // notification = ();
- // }
- // }
return (
@@ -171,6 +168,8 @@ const _render = (props: any): any => {
+
+
);
diff --git a/src/js/components/wallet/summary/Summary.js b/src/js/components/wallet/summary/Summary.js
index 5c583fc7..d728e58a 100644
--- a/src/js/components/wallet/summary/Summary.js
+++ b/src/js/components/wallet/summary/Summary.js
@@ -31,42 +31,45 @@ const _render = (props: any): any => {
) : null }
- Address #{ parseInt(props.match.params.address) + 1 }
+ Address #{ parseInt(props.match.params.address) + 1 }
-
+
+ Tokens
+ {/* 0x58cda554935e4a1f2acbe15f8757400af275e084 */}
- 0x58cda554935e4a1f2acbe15f8757400af275e084
{
- console.log("TODO: filter already added", opt, str, values);
- return opt;
+ (options, search, values) => {
+ return options.filter(o => {
+ return !tokens.find(t => t.symbol === o.symbol);
+ });
}
}
-
value={ props.summary.selectedToken }
onChange={ token => props.summaryActions.selectToken(token, account) }
valueKey="symbol"
labelKey="symbol"
placeholder="Search for token"
- loadOptions={ props.summaryActions.loadTokens }
+ searchPromptText="Type token name or address"
+ noResultsText="Token not found"
+ loadOptions={ input => props.summaryActions.loadTokens(input, account) }
backspaceRemoves={true} />
-
+
diff --git a/src/js/components/wallet/summary/SummaryContainer.js b/src/js/components/wallet/summary/SummaryContainer.js
index 18d6717f..3b9d8df9 100644
--- a/src/js/components/wallet/summary/SummaryContainer.js
+++ b/src/js/components/wallet/summary/SummaryContainer.js
@@ -16,7 +16,8 @@ function mapStateToProps(state, own) {
discovery: state.discovery,
tokens: state.tokens,
summary: state.summary,
- fiatRate: state.web3.fiatRate
+ fiat: state.fiat,
+ localStorage: state.localStorage
};
}
diff --git a/src/js/components/wallet/summary/SummaryDetails.js b/src/js/components/wallet/summary/SummaryDetails.js
index f685f838..552e7f18 100644
--- a/src/js/components/wallet/summary/SummaryDetails.js
+++ b/src/js/components/wallet/summary/SummaryDetails.js
@@ -2,34 +2,60 @@
'use strict';
import React from 'react';
+import BigNumber from 'bignumber.js';
const SummaryDetails = (props: any): any => {
- if (!props.summary.details) {
- return (
-
-
+ if (!props.summary.details) return (
+
+ );
+
+ const { config } = props.localStorage;
+ const selectedCoin = config.coins.find(c => c.network === props.coin);
+ const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
+
+ let balanceColumn = null;
+ let rateColumn = null;
+
+ if (fiatRate) {
+
+ const accountBalance = new BigNumber(props.balance);
+ const fiatValue = new BigNumber(fiatRate.value);
+ const fiat = accountBalance.times(fiatValue).toFixed(2);
+
+ balanceColumn = (
+
+
Balance
+
${ fiat }
+
{ props.balance } { selectedCoin.symbol }
+
+ );
+
+ rateColumn = (
+
+
Rate
+
${ fiatValue.toFixed(2) }
+
1.00 { selectedCoin.symbol }
)
+ } else {
+ balanceColumn = (
+
+
Balance
+
{ props.balance } { selectedCoin.symbol }
+
+ );
}
-
- const fiatValue = "0";
return (
-
+
+
-
-
Balance
-
${ fiatValue }
-
{ props.balance } ETH
-
-
-
Rate
-
${ props.fiatRate }
-
1.00 ETH
-
+ { balanceColumn }
+ { rateColumn }
-
);
}
diff --git a/src/js/components/wallet/summary/SummaryTokens.js b/src/js/components/wallet/summary/SummaryTokens.js
index 22c261e3..a4fdf771 100644
--- a/src/js/components/wallet/summary/SummaryTokens.js
+++ b/src/js/components/wallet/summary/SummaryTokens.js
@@ -13,10 +13,6 @@ const SummaryTokens = (props: any): any => {
const textColor = new ColorHash();
const tokens = props.tokens.map((t, i) => {
-
- // if (search.length > 0) {
- // if (t.name.toLowerCase().indexOf(search) < 0 && t.shortcut.toLowerCase().indexOf(search) < 0) return null;
- // }
let iconColor = {
color: textColor.hex(t.name),
background: bgColor.hex(t.name),
@@ -30,7 +26,8 @@ const SummaryTokens = (props: any): any => {
{ t.name }
- { t.balance }
+ { t.balance } { t.symbol }
+
)
});
diff --git a/src/js/containers/AsideContainer.js b/src/js/containers/AsideContainer.js
index d1a66594..12171cbe 100644
--- a/src/js/containers/AsideContainer.js
+++ b/src/js/containers/AsideContainer.js
@@ -15,7 +15,7 @@ function mapStateToProps(state, own) {
accounts: state.accounts,
router: state.router,
deviceDropdownOpened: state.DOM.deviceDropdownOpened,
- fiatRate: state.web3.fiatRate,
+ fiat: state.fiat,
localStorage: state.localStorage,
discovery: state.discovery
};
diff --git a/src/js/containers/ContentContainer.js b/src/js/containers/ContentContainer.js
index 620ebbc6..5ca6313d 100644
--- a/src/js/containers/ContentContainer.js
+++ b/src/js/containers/ContentContainer.js
@@ -13,6 +13,7 @@ import Footer from '../components/common/Footer';
import AccountTabs from '../components/wallet/account/AccountTabs';
import * as TrezorConnectActions from '../actions/TrezorConnectActions';
+import * as LogActions from '../actions/LogActions';
const Article = (props) => {
return (
@@ -20,8 +21,8 @@ const Article = (props) => {
- {/* */}
+
{ props.children }
@@ -30,13 +31,13 @@ const Article = (props) => {
function mapStateToProps(state, own) {
return {
-
+
};
}
function mapDispatchToProps(dispatch) {
return {
-
+
};
}
diff --git a/src/js/containers/LandingPageContainer.js b/src/js/containers/LandingPageContainer.js
index e48f66de..bb10e3ef 100644
--- a/src/js/containers/LandingPageContainer.js
+++ b/src/js/containers/LandingPageContainer.js
@@ -6,6 +6,7 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import LandingPage from '../components/landing/LandingPage';
+import * as LogActions from '../actions/LogActions';
function mapStateToProps(state, own) {
return {
@@ -19,6 +20,7 @@ function mapStateToProps(state, own) {
function mapDispatchToProps(dispatch) {
return {
+
};
}
diff --git a/src/js/containers/SendFormContainer.js b/src/js/containers/SendFormContainer.js
index 6c63c3e3..41f67113 100644
--- a/src/js/containers/SendFormContainer.js
+++ b/src/js/containers/SendFormContainer.js
@@ -15,8 +15,10 @@ function mapStateToProps(state, own) {
accounts: state.accounts,
discovery: state.discovery,
tokens: state.tokens,
+ pending: state.pending,
sendForm: state.sendForm,
- fiatRate: state.web3.fiatRate
+ fiat: state.fiat,
+ localStorage: state.localStorage
};
}
diff --git a/src/js/flowtype/index.js b/src/js/flowtype/index.js
new file mode 100644
index 00000000..973ffe28
--- /dev/null
+++ b/src/js/flowtype/index.js
@@ -0,0 +1,8 @@
+/* @flow */
+'use strict';
+
+
+export type Dispatch = (action: Action | ThunkAction | PromiseAction) => any;
+export type GetState = () => State;
+export type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;
+export type PromiseAction = Promise;
\ No newline at end of file
diff --git a/src/js/index.js b/src/js/index.js
index 6b77704f..f499d60b 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -7,18 +7,18 @@ import store from './store';
import router from './router';
import { onResize, onBeforeUnload } from './actions/AppActions';
+import Raven from 'raven-js';
+
import styles from '../styles/index.less';
+
+Raven.config('https://497392c3ff6e46dc9e54eef123979378@sentry.io/294339').install();
+
render(
router,
document.getElementById('root')
);
-// handle resize event and pass it to DOM reducer
-window.addEventListener('resize', () => {
- store.dispatch( onResize() );
-});
-
window.onbeforeunload = () => {
store.dispatch( onBeforeUnload() );
}
diff --git a/src/js/reducers/FiatRateReducer.js b/src/js/reducers/FiatRateReducer.js
new file mode 100644
index 00000000..0a493320
--- /dev/null
+++ b/src/js/reducers/FiatRateReducer.js
@@ -0,0 +1,37 @@
+/* @flow */
+'use strict';
+
+export type Fiat = {
+ +network: string;
+ value: string;
+}
+
+export const initialState: Array = [];
+
+const update = (state: Array, action: any): Array => {
+ const newState: Array = [ ...state ];
+ const exists: ?Fiat = newState.find(f => f.network === action.network);
+ if (exists) {
+ exists.value = action.rate.price_usd;
+ } else {
+ newState.push({
+ network: action.network,
+ value: action.rate.price_usd
+ })
+ }
+ return newState;
+}
+
+
+export default (state: Array = initialState, action: any): Array => {
+
+ switch (action.type) {
+
+ case 'rate__update' :
+ return update(state, action);
+
+ default:
+ return state;
+ }
+
+}
\ No newline at end of file
diff --git a/src/js/reducers/LogReducer.js b/src/js/reducers/LogReducer.js
new file mode 100644
index 00000000..7bcc1262
--- /dev/null
+++ b/src/js/reducers/LogReducer.js
@@ -0,0 +1,46 @@
+/* @flow */
+'use strict';
+
+type LogEntry = {
+ time: number;
+ type: string;
+ messgage: string;
+}
+
+export type State = {
+ opened: boolean;
+ entries: Array;
+}
+
+export const initialState: State = {
+ opened: false,
+ entries: [],
+};
+
+
+export default (state: State = initialState, action: any): State => {
+
+ switch (action.type) {
+
+ case 'log__open':
+ return {
+ ...state,
+ opened: true
+ }
+
+ case 'log__close':
+ return {
+ ...state,
+ opened: false
+ }
+
+ case 'log__add':
+ return {
+ ...state,
+ }
+
+ default:
+ return state;
+ }
+
+}
\ No newline at end of file
diff --git a/src/js/reducers/PendingTxReducer.js b/src/js/reducers/PendingTxReducer.js
new file mode 100644
index 00000000..0f4297bd
--- /dev/null
+++ b/src/js/reducers/PendingTxReducer.js
@@ -0,0 +1,54 @@
+/* @flow */
+'use strict';
+
+import * as SEND from '../actions/constants/SendForm';
+import * as WEB3 from '../actions/constants/Web3';
+
+export type PendingTx = {
+ +id: string;
+ +coin: string;
+ +token: string;
+ +amount: string;
+ +address: string;
+}
+
+const initialState: Array = [];
+
+const add = (state: Array, action: any) => {
+ const newState = [ ...state ];
+ newState.push({
+ id: action.txid,
+ coin: action.address.coin,
+ token: action.token,
+ amount: action.amount,
+ address: action.address.address,
+ });
+ return newState;
+}
+
+const remove = (state: Array, action: any) => {
+ return state.filter(tx => tx.id !== action.tx.id);
+}
+
+const fromStorage = (state: Array, action: any) => {
+ return state.filter(tx => tx.id !== action.tx.id);
+}
+
+export default function pending(state: Array = initialState, action: any): any {
+
+ switch (action.type) {
+
+ case SEND.TX_COMPLETE :
+ return add(state, action);
+
+ case WEB3.PENDING_TX_RESOLVED :
+ return remove(state, action);
+
+ case 'PENDING.FROM_STORAGE' :
+ return action.payload;
+
+ default:
+ return state;
+ }
+
+}
\ No newline at end of file
diff --git a/src/js/reducers/SendFormReducer.js b/src/js/reducers/SendFormReducer.js
index f65dc313..e0a9dfcb 100644
--- a/src/js/reducers/SendFormReducer.js
+++ b/src/js/reducers/SendFormReducer.js
@@ -13,6 +13,7 @@ export type State = {
+checksum: ?string;
+accountIndex: number;
+coin: string;
+ +coinSymbol: string;
token: string;
location: string;
@@ -36,7 +37,6 @@ export type State = {
nonce: string;
total: string;
sending: boolean;
- sendingStatus: ?SendStatus;
errors: {[k: string]: string};
warnings: {[k: string]: string};
infos: {[k: string]: string};
@@ -48,15 +48,12 @@ export type FeeLevel = {
value: string;
}
-type SendStatus = {
- success: boolean;
- message: string;
-}
export const initialState: State = {
checksum: null,
accountIndex: 0,
coin: '',
+ coinSymbol: '',
token: '',
location: '',
@@ -64,8 +61,8 @@ export const initialState: State = {
untouched: true,
touched: {},
balanceNeedUpdate: false,
- //address: '',
- address: '0x574BbB36871bA6b78E27f4B4dCFb76eA0091880B',
+ address: '',
+ //address: '0x574BbB36871bA6b78E27f4B4dCFb76eA0091880B',
amount: '',
setMax: false,
feeLevels: [],
@@ -78,7 +75,6 @@ export const initialState: State = {
nonce: '0',
total: '0',
sending: false,
- sendingStatus: null,
errors: {},
warnings: {},
infos: {},
@@ -166,26 +162,32 @@ export default (state: State = initialState, action: any): State => {
return {
...state,
sending: true,
- sendingStatus: null,
}
case SEND.TX_COMPLETE :
return {
...state,
+
sending: false,
- sendingStatus: {
- success: true,
- message: action.txid
- }
+ touched: {},
+ address: '',
+ amount: '',
+ setMax: false,
+ gasPriceNeedsUpdate: false,
+ gasLimit: state.gasLimit,
+ gasPrice: state.recommendedGasPrice,
+ data: '',
+ nonce: '0',
+ total: '0',
+ errors: {},
+ warnings: {},
+ infos: {},
+
}
case SEND.TX_ERROR :
return {
...state,
sending: false,
- sendingStatus: {
- success: false,
- message: action.response
- }
}
diff --git a/src/js/reducers/TokensReducer.js b/src/js/reducers/TokensReducer.js
index 68feb7f7..455888bc 100644
--- a/src/js/reducers/TokensReducer.js
+++ b/src/js/reducers/TokensReducer.js
@@ -47,6 +47,12 @@ const forget = (state: Array, action: any): Array => {
return state.filter(t => t.checksum !== action.device.checksum);
}
+const remove = (state: Array, action: any): Array => {
+ return state.filter(t => {
+ return !(t.ethAddress === action.token.ethAddress && t.address === action.token.address);
+ });
+}
+
export default (state: Array = initialState, action: any): Array => {
switch (action.type) {
@@ -54,6 +60,9 @@ export default (state: Array = initialState, action: any): Array =
case TOKEN.ADD :
return create(state, action.payload);
+ case TOKEN.REMOVE :
+ return remove(state, action);
+
case TOKEN.SET_BALANCE :
return setBalance(state, action.payload);
diff --git a/src/js/reducers/TrezorConnectReducer.js b/src/js/reducers/TrezorConnectReducer.js
index cbae74f1..9c31b1da 100644
--- a/src/js/reducers/TrezorConnectReducer.js
+++ b/src/js/reducers/TrezorConnectReducer.js
@@ -5,7 +5,6 @@ import { TRANSPORT, DEVICE } from 'trezor-connect';
import * as CONNECT from '../actions/constants/TrezorConnect';
export type TrezorDevice = {
- initialized: boolean;
remember: boolean;
connected: boolean;
path: string;
@@ -22,7 +21,7 @@ export type TrezorDevice = {
}
export type SelectedDevice = {
- id: string;
+ id: string; // could be device path if unacquired or features.device_id
instance: ?number;
}
@@ -74,7 +73,6 @@ const mergeDevices = (current: TrezorDevice, upcoming: Object): TrezorDevice =>
// ...current,
...upcoming,
// make sure that instance specific variables will not be overridden
- initialized: current.initialized,
connected: typeof upcoming.connected === 'boolean' ? upcoming.connected : current.connected,
remember: typeof upcoming.remember === 'boolean' ? upcoming.remember : current.remember,
instance: current.instance,
@@ -106,12 +104,11 @@ const addDevice = (state: State, device: Object): State => {
let affectedDevices: Array = [];
let otherDevices: Array = [];
if (device.unacquired) {
- // connected device is unacquired, but it was already merged with saved devices
- // when DEVICE.CHANGE event occurs
- // ignore this event
+ // check if connected device is unacquired, but it was already merged with saved device(s) after DEVICE.CHANGE action
affectedDevices = newState.devices.filter(d => d.path === device.path);
const diff = newState.devices.filter(d => affectedDevices.indexOf(d) === -1);
+ // if so, ignore this action
if (affectedDevices.length > 0) {
return state;
}
@@ -129,13 +126,11 @@ const addDevice = (state: State, device: Object): State => {
const newDevice: TrezorDevice = {
...device,
- initialized: false,
acquiring: false,
remember: false,
connected: true,
path: device.path,
label: device.label,
- id: 'ABCD',
checksum: null,
// instance: 0,
instanceLabel: device.label,
@@ -158,7 +153,6 @@ const setDeviceState = (state: State, action: any): State => {
if (index > -1) {
const changedDevice: TrezorDevice = {
...newState.devices[index],
- initialized: true,
checksum: action.checksum
};
newState.devices[index] = changedDevice;
@@ -251,7 +245,8 @@ const forgetDevice = (state: State, action: any): State => {
newState.devices.splice(newState.devices.indexOf(action.device), 1);
} else {
// remove all instances after disconnect (remember request declined)
- newState.devices = state.devices.filter(d => d.path !== action.device.path);
+ //newState.devices = state.devices.filter(d => d.path !== action.device.path);
+ newState.devices = state.devices.filter(d => (d.features && d.features.device_id !== action.device.features.device_id) || (!d.features && d.path !== action.device.path));
}
return newState;
@@ -277,13 +272,11 @@ const duplicate = (state: State, device: any): State => {
// if (affectedDevices.length > 0) {
const newDevice: TrezorDevice = {
...device,
- initialized: false,
checksum: null,
remember: device.remember,
connected: device.connected,
path: device.path,
label: device.label,
- id: 'ABCD',
instance: new Date().getTime(),
instanceLabel: device.instanceLabel,
ts: 0,
diff --git a/src/js/reducers/index.js b/src/js/reducers/index.js
index 11c06cd1..cd2d494a 100644
--- a/src/js/reducers/index.js
+++ b/src/js/reducers/index.js
@@ -5,6 +5,7 @@ import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
import DOM from './AppReducer.js';
+import log from './LogReducer.js';
import localStorage from './LocalStorageReducer.js';
import connect from './TrezorConnectReducer.js';
import notifications from './NotificationReducer.js';
@@ -17,10 +18,13 @@ import receive from './ReceiveReducer.js';
import summary from './SummaryReducer.js';
import tokens from './TokensReducer.js';
import discovery from './DiscoveryReducer.js';
+import pending from './PendingTxReducer.js';
+import fiat from './FiatRateReducer.js';
export default combineReducers({
router: routerReducer,
DOM,
+ log,
localStorage,
connect,
notifications,
@@ -32,5 +36,7 @@ export default combineReducers({
receive,
summary,
tokens,
- discovery
+ discovery,
+ pending,
+ fiat
});
\ No newline at end of file
diff --git a/src/js/services/CoinmarketcapService.js b/src/js/services/CoinmarketcapService.js
index 67047b09..f602dd44 100644
--- a/src/js/services/CoinmarketcapService.js
+++ b/src/js/services/CoinmarketcapService.js
@@ -7,13 +7,17 @@ import { resolveAfter } from '../utils/promiseUtils';
const loadRateAction = (): any => {
return async (dispatch, getState) => {
+ const config = getState().localStorage.config;
try {
- const rate = await httpRequest('https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=USD', 'json');
- dispatch({
- type: 'rate__update',
- rate: rate[0]
- })
+ for (let i = 0; i < config.fiatValueTickers.length; i++) {
+ const rate = await httpRequest(`${config.fiatValueTickers[i].url}?convert=USD`, 'json');
+ dispatch({
+ type: 'rate__update',
+ network: config.fiatValueTickers[i].network,
+ rate: rate[0]
+ });
+ }
} catch(error) {
@@ -29,11 +33,12 @@ const loadRateAction = (): any => {
*/
const LocalStorageService = (store: any) => (next: any) => (action: any) => {
- if (action.type === LOCATION_CHANGE && !store.getState().router.location) {
+ next(action);
+
+ //if (action.type === LOCATION_CHANGE && !store.getState().router.location) {
+ if (action.type === 'storage__ready') {
store.dispatch(loadRateAction());
}
-
- next(action);
};
export default LocalStorageService;
\ No newline at end of file
diff --git a/src/js/services/LocalStorageService.js b/src/js/services/LocalStorageService.js
index 4cb8d915..4c8f5e87 100644
--- a/src/js/services/LocalStorageService.js
+++ b/src/js/services/LocalStorageService.js
@@ -10,6 +10,8 @@ import * as MODAL from '../actions/constants/Modal';
import * as TOKEN from '../actions/constants/Token';
import * as ADDRESS from '../actions/constants/Address';
import * as DISCOVERY from '../actions/constants/Discovery';
+import * as SEND from '../actions/constants/SendForm';
+import * as WEB3 from '../actions/constants/Web3';
// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js
@@ -34,10 +36,17 @@ const findDiscovery = (devices, discovery) => {
}, []);
}
+const findPendingTxs = (accounts, pending) => {
+ return accounts.reduce((arr, account) => {
+ return arr.concat(pending.filter(a => a.address === account.address));
+ }, []);
+}
+
const save = (dispatch, getState) => {
const devices = getState().connect.devices.filter(d => d.remember === true && !d.unacquired);
const accounts = findAccounts(devices, getState().accounts);
const tokens = findTokens(accounts, getState().tokens);
+ const pending = findPendingTxs(accounts, getState().pending);
const discovery = findDiscovery(devices, getState().discovery);
// save devices
@@ -51,6 +60,9 @@ const save = (dispatch, getState) => {
// tokens
dispatch( LocalStorageActions.save('tokens', JSON.stringify( tokens ) ) );
+
+ // pending transactions
+ dispatch( LocalStorageActions.save('pending', JSON.stringify( pending ) ) );
}
@@ -74,6 +86,7 @@ const LocalStorageService = (store: any) => (next: any) => (action: any) => {
break;
case TOKEN.ADD :
+ case TOKEN.REMOVE :
case TOKEN.SET_BALANCE :
save(store.dispatch, store.getState);
// store.dispatch( LocalStorageActions.save('tokens', JSON.stringify( tokens ) ) );
@@ -103,6 +116,11 @@ const LocalStorageService = (store: any) => (next: any) => (action: any) => {
// store.dispatch( LocalStorageActions.save('selectedDevice', JSON.stringify( store.getState().connect.selectedDevice ) ) );
break;
+ case SEND.TX_COMPLETE :
+ case WEB3.PENDING_TX_RESOLVED :
+ save(store.dispatch, store.getState);
+ break;
+
}
diff --git a/src/js/services/RouterService.js b/src/js/services/RouterService.js
index 2088e529..83e37603 100644
--- a/src/js/services/RouterService.js
+++ b/src/js/services/RouterService.js
@@ -38,7 +38,7 @@ const validation = (store: any, params: UrlParams): boolean => {
if (params.hasOwnProperty('device')) {
const { devices } = store.getState().connect;
- let device; // = devices.find(d => d.path === params.device || d.features.device_id === params.device);
+ let device;
if (params.hasOwnProperty('deviceInstance')) {
device = devices.find(d => d.features && d.features.device_id === params.device && d.instance === params.deviceInstance );
} else {
@@ -50,7 +50,7 @@ const validation = (store: any, params: UrlParams): boolean => {
if (params.hasOwnProperty('coin')) {
const { config } = store.getState().localStorage;
- const coin = config.coins.find(c => c.symbol === params.coin);
+ const coin = config.coins.find(c => c.network === params.coin);
if (!coin) return false;
if (!params.address) return false;
}
diff --git a/src/js/services/TrezorConnectService.js b/src/js/services/TrezorConnectService.js
index 8776e6ba..d233c554 100644
--- a/src/js/services/TrezorConnectService.js
+++ b/src/js/services/TrezorConnectService.js
@@ -16,7 +16,7 @@ import * as ACTIONS from '../actions';
const TrezorConnectService = (store: any) => (next: any) => (action: any) => {
const prevState = store.getState().connect;
- const prevModalState = store.getState().connect;
+ const prevModalState = store.getState().modal;
next(action);
@@ -32,6 +32,22 @@ const TrezorConnectService = (store: any) => (next: any) => (action: any) => {
} else if (action.type === DEVICE.DISCONNECT) {
store.dispatch( TrezorConnectActions.deviceDisconnect(action.device) );
+ } else if (action.type === CONNECT.REMEMBER_REQUEST) {
+ // TODO:
+ if (prevModalState.opened && prevModalState.windowType === CONNECT.REMEMBER_REQUEST) {
+
+
+ store.dispatch({
+ type: CONNECT.FORGET,
+ device: store.getState().modal.device
+ });
+
+ store.dispatch({
+ type: CONNECT.FORGET,
+ device: prevModalState.device
+ });
+ }
+
} else if (action.type === CONNECT.FORGET) {
//store.dispatch( TrezorConnectActions.forgetDevice(action.device) );
store.dispatch( TrezorConnectActions.switchToFirstAvailableDevice() );
@@ -62,6 +78,7 @@ const TrezorConnectService = (store: any) => (next: any) => (action: any) => {
// interrupt process of remembering device (force forget)
// TODO: the same for disconnect more than 1 device at once
+ // TODO: move it to modal actions
const { modal } = store.getState();
if (modal.opened && modal.windowType === CONNECT.REMEMBER_REQUEST) {
if (action.device.features && modal.device.features.device_id === action.device.features.device_id) {
diff --git a/src/js/store/store.dev.js b/src/js/store/store.dev.js
index 4120d399..ea745560 100644
--- a/src/js/store/store.dev.js
+++ b/src/js/store/store.dev.js
@@ -12,6 +12,7 @@ import reducers from '../reducers';
import services from '../services';
import { Middleware } from 'redux';
import { GenericStoreEnhancer } from 'redux';
+import RavenMiddleware from 'redux-raven-middleware';
export const history = createHistory( { queryKey: false } );
@@ -19,6 +20,7 @@ const initialState: any = {};
const enhancers = [];
const middleware = [
thunk,
+ RavenMiddleware('https://497392c3ff6e46dc9e54eef123979378@sentry.io/294339'),
routerMiddleware(history)
];
diff --git a/src/solidity/rinkeby-token.js b/src/solidity/rinkeby-token.js
new file mode 100644
index 00000000..1f00c95c
--- /dev/null
+++ b/src/solidity/rinkeby-token.js
@@ -0,0 +1,137 @@
+pragma solidity ^0.4.4;
+
+contract Token {
+
+ /// @return total amount of tokens
+ function totalSupply() constant returns (uint256 supply) {}
+
+ /// @param _owner The address from which the balance will be retrieved
+ /// @return The balance
+ function balanceOf(address _owner) constant returns (uint256 balance) {}
+
+ /// @notice send `_value` token to `_to` from `msg.sender`
+ /// @param _to The address of the recipient
+ /// @param _value The amount of token to be transferred
+ /// @return Whether the transfer was successful or not
+ function transfer(address _to, uint256 _value) returns (bool success) {}
+
+ /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
+ /// @param _from The address of the sender
+ /// @param _to The address of the recipient
+ /// @param _value The amount of token to be transferred
+ /// @return Whether the transfer was successful or not
+ function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
+
+ /// @notice `msg.sender` approves `_addr` to spend `_value` tokens
+ /// @param _spender The address of the account able to transfer the tokens
+ /// @param _value The amount of wei to be approved for transfer
+ /// @return Whether the approval was successful or not
+ function approve(address _spender, uint256 _value) returns (bool success) {}
+
+ /// @param _owner The address of the account owning tokens
+ /// @param _spender The address of the account able to transfer the tokens
+ /// @return Amount of remaining tokens allowed to spent
+ function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
+
+ event Transfer(address indexed _from, address indexed _to, uint256 _value);
+ event Approval(address indexed _owner, address indexed _spender, uint256 _value);
+
+}
+
+
+
+contract StandardToken is Token {
+
+ function transfer(address _to, uint256 _value) returns (bool success) {
+ //Default assumes totalSupply can't be over max (2^256 - 1).
+ //If your token leaves out totalSupply and can issue more tokens as time goes on, you need to check if it doesn't wrap.
+ //Replace the if with this one instead.
+ //if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
+ if (balances[msg.sender] >= _value && _value > 0) {
+ balances[msg.sender] -= _value;
+ balances[_to] += _value;
+ Transfer(msg.sender, _to, _value);
+ return true;
+ } else { return false; }
+ }
+
+ function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
+ //same as above. Replace this line with the following if you want to protect against wrapping uints.
+ //if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
+ if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
+ balances[_to] += _value;
+ balances[_from] -= _value;
+ allowed[_from][msg.sender] -= _value;
+ Transfer(_from, _to, _value);
+ return true;
+ } else { return false; }
+ }
+
+ function balanceOf(address _owner) constant returns (uint256 balance) {
+ return balances[_owner];
+ }
+
+ function approve(address _spender, uint256 _value) returns (bool success) {
+ allowed[msg.sender][_spender] = _value;
+ Approval(msg.sender, _spender, _value);
+ return true;
+ }
+
+ function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
+ return allowed[_owner][_spender];
+ }
+
+ mapping (address => uint256) balances;
+ mapping (address => mapping (address => uint256)) allowed;
+ uint256 public totalSupply;
+}
+
+
+//name this contract whatever you'd like
+contract DariaCoin is StandardToken {
+
+ function () {
+ //if ether is sent to this address, send it back.
+ throw;
+ }
+
+ /* Public variables of the token */
+
+ /*
+ NOTE:
+ The following variables are OPTIONAL vanities. One does not have to include them.
+ They allow one to customise the token contract & in no way influences the core functionality.
+ Some wallets/interfaces might not even bother to look at this information.
+ */
+ string public name; //fancy name: eg Simon Bucks
+ uint8 public decimals; //How many decimals to show. ie. There could 1000 base units with 3 decimals. Meaning 0.980 SBX = 980 base units. It's like comparing 1 wei to 1 ether.
+ string public symbol; //An identifier: eg SBX
+ string public version = 'H1.0'; //human 0.1 standard. Just an arbitrary versioning scheme.
+
+//
+// CHANGE THESE VALUES FOR YOUR TOKEN
+//
+
+//make sure this function name matches the contract name above. So if you're token is called TutorialToken, make sure the //contract name above is also TutorialToken instead of ERC20Token
+
+ function DariaCoin(
+ ) {
+ balances[msg.sender] = 666; // Give the creator all initial tokens (100000 for example)
+ totalSupply = 666; // Update total supply (100000 for example)
+ name = "Daria Coin :)"; // Set the name for display purposes
+ decimals = 2; // Amount of decimals for display purposes
+ symbol = "DC!"; // Set the symbol for display purposes
+ }
+
+ /* Approves and then calls the receiving contract */
+ function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
+ allowed[msg.sender][_spender] = _value;
+ Approval(msg.sender, _spender, _value);
+
+ //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
+ //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
+ //it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
+ if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { throw; }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/styles/aside.less b/src/styles/aside.less
index f2e5954b..107069ad 100644
--- a/src/styles/aside.less
+++ b/src/styles/aside.less
@@ -11,6 +11,7 @@ aside {
width: 320px;
height: 64px;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
+ background: @color_white;
.Select-control {
height: 63px;
@@ -43,9 +44,9 @@ aside {
.Select-arrow {
visibility: hidden;
- &:after {
- content: ''
- }
+ // &:after {
+ // content: ''
+ // }
}
.device {
@@ -197,10 +198,10 @@ aside {
color: @color_text_primary;
height: 50px;
- .hover();
+ transition: background-color 0.3s, color 0.3s;
&:hover {
- background: @color_gray_light;
+ background-color: @color_gray_light;
}
&.account {
@@ -216,21 +217,49 @@ aside {
color: @color_text_secondary;
}
- // &:last-child {
- // border-bottom: 1px solid @color_divider;
- // }
- }
-
- &.selected {
- background: @color_white;
- border-left: 3px solid @color_green_primary;
- padding-left: 27px;
+ &:before {
+ content: '';
+ width: 0px;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: @color_green_primary;
+ transition: width 0.3s;
+ }
- &:hover {
+ &.selected {
background: @color_white;
+ //border-left: 3px solid @color_green_primary;
+ //border-bottom: 1px solid @color_divider;
+ //padding-left: 27px;
+
+ &:before {
+ width: 3px;
+ }
+
+ &:hover {
+ background: @color_white;
+ }
+
+ &:last-child {
+ // border-bottom: 1px solid @color_divider;
+ &:after {
+ content: '';
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ width: 100%;
+ height: 1px;
+ line-height: 1px;
+ background-color: @color_divider;
+ }
+ }
}
}
+
+
&.coin {
padding-left: 80px;
&:before {
@@ -303,15 +332,16 @@ aside {
}
}
+ &.ropsten:before,
&.eth:before {
background-image: url('../images/eth-logo.png');
background-size: auto 20px;
}
+ &.rinkeby:before,
&.etc:before {
background-image: url('../images/etc-logo.png');
background-size: auto 20px;
}
-
&.btc:before {
background-image: url('../images/btc-logo.png');
}
@@ -330,8 +360,6 @@ aside {
&.zec:before {
background-image: url('../images/zec-logo.png');
}
-
-
}
.coin-divider {
@@ -387,7 +415,7 @@ aside {
.add-address {
position: relative;
- padding: 4px 0 4px 20px;
+ padding: 8px 0 8px 20px;
cursor: pointer;
color: @color_text_secondary;
display: flex;
@@ -425,11 +453,12 @@ aside {
flex-direction: row;
align-items: center;
font-size: 14px;
- padding: 16px 0 16px 30px;
+ padding: 8px 0 8px 22px;
white-space: nowrap;
- border-top: 1px solid @color_divider;
+ color: @color_text_secondary;
+ //border-top: 1px solid @color_divider;
.loader-circle {
- margin-right: 12px;
+ margin-right: 14px;
}
}
diff --git a/src/styles/base.less b/src/styles/base.less
index 1a3aa928..54d6d27d 100644
--- a/src/styles/base.less
+++ b/src/styles/base.less
@@ -19,7 +19,7 @@ html, body {
position: relative;
background-color: @color_body;
font-family: @font-default;
- font-weight: 300;
+ font-weight: 400;
font-size: 14px;
}
diff --git a/src/styles/colors.less b/src/styles/colors.less
index 45f974c9..ab3a8d50 100644
--- a/src/styles/colors.less
+++ b/src/styles/colors.less
@@ -1,17 +1,15 @@
@color_white: #ffffff;
@color_header: #212121;
-@color_body: #EBEBEB;
+@color_body: #E3E3E3;
@color_main: #FBFBFB;
@color_landing: #F9F9F9;
-/// new!!!
-
-@color_text_primary: #505050;
-@color_text_secondary: #A9A9A9;
+@color_text_primary: #494949;
+@color_text_secondary: #757575;
@color_gray_light: #F2F2F2; // hover menu
-@color_divider: #EBEBEB;
+@color_divider: #E3E3E3; //#EBEBEB;
@color_green_primary: #01B757;
@color_green_secondary: #00AB51;
diff --git a/src/styles/content.less b/src/styles/content.less
index 6390f93e..f203e483 100644
--- a/src/styles/content.less
+++ b/src/styles/content.less
@@ -12,11 +12,12 @@ article {
position: relative;
.account-tabs {
+ position: relative;
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
- padding: 0px 48px;
+ padding: 0px 28px; // 20px padding arround links
max-width: 600px;
a {
@@ -24,6 +25,9 @@ article {
font-size: 14px;
color: @color_text_secondary;
margin: 0px 4px;
+ padding: 20px;
+ .hover();
+
&.active,
&:hover {
color: @color_text_primary;
@@ -37,6 +41,16 @@ article {
margin-right: 0px;
}
}
+
+ .indicator {
+ position: absolute;
+ bottom: -1px;
+ left: 0;
+ width: 100px;
+ height: 2px;
+ background: @color_green_primary;
+ transition: all 0.3s ease-in-out;
+ }
}
}
@@ -48,7 +62,7 @@ article {
h2 {
font-size: 16px;
- font-weight: 500;
+ font-weight: 600;
padding: 24px 48px;
}
diff --git a/src/styles/fonts.less b/src/styles/fonts.less
index 81328954..51bb91e5 100644
--- a/src/styles/fonts.less
+++ b/src/styles/fonts.less
@@ -19,15 +19,6 @@
url('../fonts/roboto/roboto-mono-v4-greek_cyrillic-ext_greek-ext_latin_cyrillic_vietnamese_latin-ext-regular.svg#RobotoMono') format('svg'); /* Legacy iOS */
}
-@font-face {
- font-family: 'glyphicons';
- src: url('../fonts/glyphicons.eot') format('embedded-opentype'),
- url('../fonts/glyphicons.eot?#iefix') format('embedded-opentype'),
- url('../fonts/glyphicons.woff') format('woff'),
- url('../fonts/glyphicons.ttf') format('truetype'),
- url('../fonts/glyphicons.svg#icomoon') format('svg');
-}
-
@font-face {
font-family: 'icomoon';
src: url('../fonts/icomoon.eot') format('embedded-opentype'),
@@ -37,11 +28,6 @@
url('../fonts/icomoon.svg#icomoon') format('svg');
}
-@font-face {
- font-family: 'fontello';
- src: url('../fonts/pass.ttf') format('truetype');
-}
-
@font-default: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
@font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", Arial, sans-serif;
@font-family-monospace: "Roboto Mono", Menlo, Monaco, Consolas, "Courier New", monospace;
@@ -52,74 +38,6 @@
// background: @color_info_secondary;
// }
-.glyphicon-base() {
- display: inline-block;
- font-family: 'glyphicons';
- font-style: normal;
- font-weight: normal;
- line-height: 1;
-}
-
-.glyphicon-trezor {
- .glyphicon-base();
- content: "\5f";
- padding-top: 1px;
- font-size: 14px;
-}
-
-.glyphicon-info {
- .glyphicon-base();
- content: "\ea0c";
-}
-
-.glyphicon-warning {
- .glyphicon-base();
- content: "\ea07";
-}
-
-.glyphicon-cross {
- .glyphicon-base();
- content: "\ea0f";
-}
-
-.glyphicon-checkmark {
- .glyphicon-base();
- content: "\ea10";
-}
-
-.glyphicon-up {
- .glyphicon-base();
- content: "\e113";
-}
-
-.glyphicon-down {
- .glyphicon-base();
- content: "\e114";
-}
-
-.glyphicon-eye-open {
- .glyphicon-base();
- content: "\e105";
-}
-
-.glyphicon-settings {
- .glyphicon-base();
- content: "\e019";
-}
-
-.glyphicon-refresh {
- .glyphicon-base();
- content: "\e031";
-}
-
-.glyphicon-plus {
- .glyphicon-base();
- content: "\2b";
- position: relative;
- top: 1px;
-}
-
-
.icomoon-base() {
display: inline-block;
font-family: 'icomoon';
@@ -140,14 +58,14 @@
content: "\e902";
}
-.icomoon-info {
+.icomoon-refresh {
.icomoon-base();
- content: "\e904";
+ content: "\e903";
}
-.icomoon-refresh {
+.icomoon-info {
.icomoon-base();
- content: "\e903";
+ content: "\e904";
}
.icomoon-chat {
@@ -175,37 +93,27 @@
content: "\e909";
}
-.icomoon-eye-error {
- .icomoon-base();
- content: "\e912";
-}
-
-.icomoon-T1 {
- .icomoon-base();
- content: "\e913";
-}
-
.icomoon-close {
.icomoon-base();
content: "\e90a";
}
-.icomoon-arrow-left {
+.icomoon-arrow-up {
.icomoon-base();
content: "\e90b";
}
-.icomoon-arrow-up {
+.icomoon-arrow-right2 {
.icomoon-base();
content: "\e90c";
}
-.icomoon-arrow-right {
+.icomoon-plus {
.icomoon-base();
content: "\e90d";
}
-.icomoon-plus {
+.icomoon-arrow-right {
.icomoon-base();
content: "\e90e";
}
@@ -216,6 +124,24 @@
}
+.icomoon-eye-error {
+ .icomoon-base();
+ content: "\e911";
+}
+
+.icomoon-T1 {
+ .icomoon-base();
+ content: "\e912";
+}
+
+
+
+.icomoon-arrow-left {
+ .icomoon-base();
+ content: "\e91a";
+}
+
+
.icomoon-setmax {
.icomoon-base();
content: "\e91b";
@@ -235,3 +161,8 @@
.icomoon-base();
content: "\e91e";
}
+
+.icomoon-back {
+ .icomoon-base();
+ content: "\e91f";
+}
diff --git a/src/styles/header.less b/src/styles/header.less
index 462c7b83..b3a680e9 100644
--- a/src/styles/header.less
+++ b/src/styles/header.less
@@ -7,21 +7,31 @@ header {
fill: @color_white;
height: 28px;
width: 100px;
- margin-top: 9px;
- display: inline-block;
- }
-
- span {
- display: inline-block;
- vertical-align: top;
- margin-top: 16px;
- margin-left: 20px;
+ flex: 1;
}
.layout-wrapper {
width: 100%;
+ height: 100%;
max-width: 1170px;
margin: 0 auto;
- padding: 0 15px;
+ padding: 0 32px;
+ display: flex;
+ align-items: center;
+ }
+
+ a, a:visited {
+ color: @color_white;
+ margin-left: 24px;
+ .hover();
+
+ &:first-child {
+ margin: 0px;
+ }
+
+ &:hover,
+ &:active {
+ color: @color_text_secondary;
+ }
}
}
diff --git a/src/styles/index.less b/src/styles/index.less
index a58f3cb6..dde75258 100644
--- a/src/styles/index.less
+++ b/src/styles/index.less
@@ -26,3 +26,4 @@
@import './inputs.less';
@import './loader.less';
+@import './log.less';
diff --git a/src/styles/inputs.less b/src/styles/inputs.less
index 84748d61..a79945f7 100644
--- a/src/styles/inputs.less
+++ b/src/styles/inputs.less
@@ -32,7 +32,7 @@ input {
&.warning {
border-color: @color_warning_primary;
&:focus {
- box-shadow: 0 1px 4px 0 rgba(1, 183, 87, 0.25);
+ box-shadow: 0 1px 4px 0 rgba(235, 138, 0, 0.25);
}
}
@@ -221,6 +221,4 @@ a.green:visited {
border-color: @color_white;
}
}
-
-
}
diff --git a/src/styles/landingPage.less b/src/styles/landingPage.less
index 31b80daa..f8e22317 100644
--- a/src/styles/landingPage.less
+++ b/src/styles/landingPage.less
@@ -9,6 +9,7 @@
text-align: center;
padding-top: 65px;
margin-top: 0px;
+ background: @color_landing;
h2.claim {
font-size: 36px;
@@ -67,6 +68,7 @@
}
.image {
+ position: relative;
width: 100%;
height: calc(100vh - 143px);
min-height: 500px;
@@ -75,6 +77,13 @@
background-repeat: no-repeat;
background-position: center 0px;
background-size: contain;
+ p {
+ position: absolute;
+ bottom: 32px;
+ left: 0;
+ right: 0;
+ margin: 0px auto;
+ }
}
img {
diff --git a/src/styles/log.less b/src/styles/log.less
new file mode 100644
index 00000000..1b69b590
--- /dev/null
+++ b/src/styles/log.less
@@ -0,0 +1,50 @@
+.log {
+ position: relative;
+ color: @color_info_primary;
+ background: @color_info_secondary;
+ padding: 24px 48px;
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+
+ .log-close {
+ position: absolute;
+ top: 8px;
+ right: 0;
+ padding: 12px;
+ color: inherit;
+ transition: opacity 0.3s;
+
+ &:after {
+ .icomoon-close;
+ }
+ &:active,
+ &:hover {
+ opacity: 0.6;
+ color: inherit;
+ }
+ }
+
+ h2 {
+ font-size: 14px;
+ font-weight: bold;
+ padding: 0px;
+ }
+
+ p {
+ padding: 0px;
+ margin: 2px 0px;
+ font-size: 12px;
+ color: inherit;
+ }
+
+ textarea {
+ width: 100%;
+ height: 200px;
+ min-height: 200px;
+ resize: vertical;
+ &:focus {
+ box-shadow: none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/styles/modal.less b/src/styles/modal.less
index d5509e98..32d774e5 100644
--- a/src/styles/modal.less
+++ b/src/styles/modal.less
@@ -19,7 +19,7 @@
border-radius: 4px;
background-color: @color_white;
text-align: center;
- overflow: hidden;
+ // overflow: hidden;
}
h3 {
@@ -157,6 +157,8 @@
height: 80px;
margin-top: 15px;
margin-left: 10px;
+ font-size: 22px;
+ font-weight: 600;
color: @color_text_primary;
border: 1px solid @color_divider;
background: @color_white;
@@ -186,10 +188,10 @@
input {
letter-spacing: 6px;
line-height: 48px;
- font-weight: bold;
- font-size: 18px;
+ font-weight: 600;
+ font-size: 32px;
height: auto;
- padding: 0px 34px;
+ padding: 0px 31px;
color: @color_text_primary;
background: transparent;
}
@@ -202,7 +204,7 @@
margin: auto 0;
padding: 0;
&:after {
- .icomoon-arrow-left;
+ .icomoon-back;
}
}
diff --git a/src/styles/notification.less b/src/styles/notification.less
index 16dd3006..7811cca7 100644
--- a/src/styles/notification.less
+++ b/src/styles/notification.less
@@ -52,7 +52,7 @@
p {
padding: 0px;
- margin-bottom: 8px 0px;
+ margin: 8px 0px;
color: inherit;
}
diff --git a/src/styles/rcTooltip.less b/src/styles/rcTooltip.less
index d2a2c5e8..644287f9 100644
--- a/src/styles/rcTooltip.less
+++ b/src/styles/rcTooltip.less
@@ -6,6 +6,11 @@
}
}
+.aside-tooltip-wrapper {
+ width: 260px;
+ font-size: 10px;
+}
+
.rc-tooltip {
position: absolute;
z-index: 1070;
diff --git a/src/styles/reactSelect.less b/src/styles/reactSelect.less
index 56f7beb2..90896298 100644
--- a/src/styles/reactSelect.less
+++ b/src/styles/reactSelect.less
@@ -1,6 +1,6 @@
// https://github.com/JedWatson/react-select/blob/master/less/select.less
-@import '~react-select/less/select';
+@import '~react-select/less/select.less';
// override predefined colors
@select-primary-color: @color_white;
@@ -10,6 +10,8 @@
@select-item-border-radius: 0px;
@select-input-border-color: transparent;
@select-input-border-focus: @color_divider;
+// @select-input-bg: transparent;
+// @select-input-bg-focus: transparent;
.Select-focus-state(@color) {
// do nothing
@@ -67,7 +69,13 @@
}
.Select-noresults {
-
+ color: @color_text_secondary;
+ font-family: @font-default;
+ }
+
+ .Select-placeholder {
+ color: @color_text_secondary;
+ font-family: @font-default;
}
.Select-value-label {
@@ -90,240 +98,3 @@
}
}
}
-
-
-
-
-
-
-
-
-
-
-/*@select-input-height: 34px;
-@select-primary-color: #fff;
-@select-input-bg-focus: #ff0000;
-@select-input-border-radius: 0px;
-@select-input-border-focus: @select-input-border-color;
-
-.Select {
- width: 240px;
- height: 34px;
- display: inline-block;
- vertical-align: middle;
-
- &.is-focused:not(.is-open) > .Select-control {
- border-color: @select-input-border-color;
- box-shadow: none;
- }
-}
-
-.Select-control {
- &:hover {
- box-shadow: none;
- }
-}
-
-
-
-
-
-.Select-menu-outer {
- border: 1px solid rgba(0, 0, 0, 0.15);
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
-}
-
-.Select-option {
- &:last-child {
- border-radius: 0px;
- }
-
- .fee-label {
- display: inline-block;
- width: 70%;
- }
- .fee-size {
- display: inline-block;
- text-align: right;
- }
-}
-
-.CurrencySelect {
- width: 70px;
- vertical-align: top;
-}
-
-
-.CoinSelect {
- width: 290px;
- height: 64px;
- .Select-control {
- height: 63px;
- border: 0px;
- border-radius: 4px 0px 0px 0px;
- border-right: 1px solid @color_divider;
- cursor: pointer;
- transition: all 0.2s ease-in-out;
-
- .Select-input {
- background: transparent;
- //display: none !important;
- }
-
- &:hover {
- background: #F2F2F2;
- .Select-arrow {
- &:after {
- color: #494949;
- }
- }
- }
- }
-
- .Select-value {
- padding: 0px;
- .Select-value-label {
- display: inline-block;
- height: 63px;
- padding-top: 20px;
- padding-left: 50px;
- font-size: 1.15em;
- font-weight: bold;
- line-height: 26px;
- color: #494949;
-
- }
- &:before {
- content: '';
- position: absolute;
- display: block;
- width: 20px;
- height: 20px;
- z-index: 2;
- left: 20px;
- top: 21px;
-
-
- background-image: url(../images/eth-logo.png);
- background-repeat: no-repeat;
- background-position: center;
- background-size: auto 20px;
- }
- }
-
- .Select-menu-outer {
- position: relative;
- top: 0;
- border: 0px;
- border-top: 1px solid rgba(218, 218, 218, 0.5);
- border-right: 1px solid rgba(218, 218, 218, 0.5);
- box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
- max-height: none;
- }
-
- .Select-menu {
- max-height: none;
- overflow-x: none;
- }
-
- .Select-option {
- width: 290px;
- height: 64px;
- padding-top: 20px;
- padding-left: 60px;
- position: relative;
- transition: all 0.2s ease-in-out;
-
- span {
- height: 63px;
- font-size: 1.15em;
- font-weight: bold;
- line-height: 26px;
- color: #494949;
- }
-
- &:before {
- content: '';
- position: absolute;
- display: block;
- width: 20px;
- height: 20px;
- z-index: 2;
- left: 20px;
- top: 21px;
- background-repeat: no-repeat;
- background-position: center;
- background-size: 20px 20px;
- }
-
- &.btc:before {
- background-image: url('../images/btc-logo.png');
- }
- &.ltc:before {
- background-image: url('../images/ltc-logo.png');
- }
- &.btg:before {
- background-image: url('../images/btg-logo.png');
- }
- &.bch:before {
- background-image: url('../images/bch-logo.png');
- }
- &.dash:before {
- background-image: url('../images/dash-logo.png');
- }
- &.zec:before {
- background-image: url('../images/zec-logo.png');
- }
- &.eth:before {
- background-image: url('../images/eth-logo.png');
- background-size: auto 20px;
- }
- &.etc:before {
- background-image: url('../images/etc-logo.png');
- background-size: auto 20px;
- }
-
- &:hover {
- background: #F2F2F2;
- }
-
- &.is-selected {
- background: yellow;
- }
- }
-
- .Select-arrow-zone {
- width: 28px;
- }
-
- .Select-arrow {
- border: 0px;
- width: 28px;
-
- &:after {
- .glyphicon-down;
- color: #B3B3B3;
- position: absolute;
- left: 0px;
- top: -8px;
- transition: all 0.2s ease-in-out;
- }
- }
-
- &.is-open {
- .Select-arrow {
- top: 0px;
- &:after {
- .glyphicon-up;
- }
- }
- }
-}
-
-
-
-// /*
-//
-//
-//
-// */
\ No newline at end of file
diff --git a/src/styles/send.less b/src/styles/send.less
index 094516e2..4d7c37d7 100644
--- a/src/styles/send.less
+++ b/src/styles/send.less
@@ -1,5 +1,4 @@
.send-form {
- padding-bottom: 24px;
.Select {
width: 98px;
@@ -27,6 +26,15 @@
}
}
+ &.is-disabled {
+ .Select-control {
+ cursor: default;
+ }
+ .Select-arrow {
+ visibility: hidden;
+ }
+ }
+
.fee-option {
display: flex;
align-items: center;
@@ -53,7 +61,7 @@
padding-bottom: 24px;
.error,
- .warning,
+ .warning:not(input),
.info {
position: absolute;
left: 48px;
@@ -65,7 +73,7 @@
.error {
color: @color_error_primary;
}
- .warning {
+ .warning:not(input) {
color: @color_warning_primary;
}
.info {
@@ -184,6 +192,8 @@
display: flex;
justify-content: space-between;
padding: 0px 48px;
+
+ padding-bottom: 24px;
button {
width: 50%;
}
@@ -283,4 +293,58 @@
resize: none;
height: 80px;
}
+
+
+ .pending-transactions {
+
+ border-top: 1px solid @color_divider;
+
+ .tx {
+ border-bottom: 1px solid @color_divider;
+ padding: 14px 48px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+
+
+ &:last-child {
+ border-bottom: 0px;
+ }
+
+ .icon {
+ width: 36px;
+ height: 36px;
+ //border: 8px solid white;
+ border-radius: 50%;
+ margin-right: 10px;
+ line-height: 30px;
+ text-transform: uppercase;
+ user-select: none;
+ text-align: center;
+ padding: 6px;
+ p {
+ line-height: 24px;
+ padding: 0px;
+ color: inherit;
+ }
+ }
+
+ .name {
+ flex: 1;
+
+ a, a:visited {
+ color: @color_text_secondary;
+ .hover();
+
+ &:hover, &:active {
+ color: @color_text_primary;
+ }
+ }
+ }
+
+ .balance {
+ color: @color_text_primary;
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/styles/summary.less b/src/styles/summary.less
index 79bd50cc..04cfee79 100644
--- a/src/styles/summary.less
+++ b/src/styles/summary.less
@@ -1,8 +1,27 @@
.summary {
- h2 {
- //padding: 35px 50px 0px 50px;
- color: red;
+ .summary-header {
+ display: flex;
+ align-items: center;
+ &:before {
+ content: '';
+ display: inline-block;
+ width: 32px;
+ height: 22px;
+ background-repeat: no-repeat;
+ background-size: 20px 20px;
+ }
+
+ &.ropsten:before,
+ &.eth:before {
+ background-image: url('../images/eth-logo.png');
+ background-size: auto 20px;
+ }
+ &.rinkeby:before,
+ &.etc:before {
+ background-image: url('../images/etc-logo.png');
+ background-size: auto 20px;
+ }
}
.token-select {
@@ -36,25 +55,26 @@
.summary-details {
position: relative;
- padding: 35px 50px 0px 50px;
+ padding: 0px 48px;
border-bottom: 1px solid @color_divider;
.content {
+ display: flex;
+ padding-bottom: 32px;
+
.column {
- display: inline-block;
- width: 25%;
- padding-bottom: 30px;
+ margin-right: 48px;
- .label {
- color: #A9A9A9;
- font-weight: 600;
+ .label, .value {
+ color: @color_text_secondary;
+ font-size: 12px;
}
.fiat-value {
- font-weight: bold;
- font-size: 1.2em;
+ font-weight: 500;
+ font-size: 18px;
margin: 7px 0 6px 0;
- color: #494949;
+ color: @color_text_primary;
}
}
}
@@ -69,45 +89,38 @@
height: 40px;
//line-height: 30px;
background: @color_white;
- color: #B3B3B3;
+ color: @color_text_secondary;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
border-radius: 50%;
cursor: pointer;
- transition: all 0.2s ease-in-out;
+ transition: all 0.3s;
&:hover {
- background: #F2F2F2;
- &:before {
- color: #494949;
- }
+ background: @color_divider;
+ color: @color_text_primary;
}
&:before {
- .glyphicon-up;
- color: #B3B3B3;
+ .icomoon-arrow-down;
+ transition: transform 0.3s;
+ transform-origin: 50% 50%;
position: absolute;
- left: 14px;
- top: 16px;
- transition: all 0.2s ease-in-out;
+ left: 8px;
+ top: 10px;
}
}
- &.closed {
- .content {
- display: none;
- }
- .toggle {
- &:before {
- .glyphicon-down;
- top: 18px;
- }
+ &.opened {
+ .toggle:before {
+ transform: rotate(180deg);
+ top: 8px;
}
}
}
.filter {
- background: @color_main;
- padding: 30px 48px 10px 48px;
+ //background: @color_main;
+ padding: 0px 48px 32px 48px;
// text-align: right;
// input {
@@ -115,78 +128,30 @@
// }
}
- .add-token-form {
- position: relative;
- .toggle {
- cursor: pointer;
- padding: 15px 50px;
- }
-
- .content {
- display: flex;
- flex-direction: row;
- padding: 15px 50px;
- }
-
-
- .column {
- padding-right: 10px;
- label {
- display: block;
- color: #A9A9A9;
- font-weight: 600;
- }
-
- input {
- &.token-address {
- width: 230px;
- }
-
- &.token-name {
- width: 160px;
- }
-
- &.token-shortcut {
- width: 80px;
- }
-
- &.token-decimal {
- width: 80px;
- }
- }
-
- button {
-
- }
- }
-
- &:after {
- .glyphicon-up;
- color: #B3B3B3;
- position: absolute;
- right: 50px;
- top: 21px;
- transition: all 0.2s ease-in-out;
+ .token-select {
+ .Select-control {
+ cursor: text;
}
- &:hover {
- &:after {
- color: #494949;
+ .Select-option {
+ .hover();
+ &.is-focused {
+ background: @color_gray_light;
}
- }
-
- &.closed {
- &:after {
- .glyphicon-down;
+
+ &.is-selected {
+ background: @color_divider;
}
}
}
.token {
border-top: 1px solid @color_divider;
- padding: 15px 50px;
+ padding: 14px 48px;
display: flex;
flex-direction: row;
+ align-items: center;
+ position: relative;
.icon {
width: 36px;
@@ -208,24 +173,27 @@
.name {
flex: 1;
- line-height: 30px;
+ color: @color_text_secondary;
}
- .balance {
- color: red;
- line-height: 30px;
+ button {
+ position: absolute;
+ right: 12px;
+ padding: 0px;
+ padding-top: 3px;
+ &:after {
+ .icomoon-close;
+ }
}
+
+
&:last-child {
// border-bottom: 1px solid @color_divider;
}
}
- .token-select {
- .Select-control {
- cursor: text;
- }
- }
+
}
diff --git a/webpack/webpack.config.dev.js b/webpack/webpack.config.dev.js
index f50c2f65..8891d939 100644
--- a/webpack/webpack.config.dev.js
+++ b/webpack/webpack.config.dev.js
@@ -1,4 +1,4 @@
-import { TREZOR_CONNECT_FILES, SRC, PORT } from './constants';
+import { TREZOR_CONNECT_FILES, TREZOR_CONNECT_HTML, SRC, PORT } from './constants';
import path from 'path';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
@@ -88,10 +88,10 @@ module.exports = {
inject: true
}),
new CopyWebpackPlugin([
- { from: `${TREZOR_CONNECT_FILES}coins.json` },
- { from: `${TREZOR_CONNECT_FILES}releases.json` },
- { from: `${TREZOR_CONNECT_FILES}latest.txt` },
- { from: `${TREZOR_CONNECT_FILES}config_signed.bin` },
+ { from: `${TREZOR_CONNECT_FILES}coins.json`, to: './data/coins.json' },
+ { from: `${TREZOR_CONNECT_FILES}releases-1.json`, to: './data/releases-1.json' },
+ { from: `${TREZOR_CONNECT_FILES}latest.txt`, to: './data/latest.txt' },
+ { from: `${TREZOR_CONNECT_FILES}config_signed.bin`, to: './data/config_signed.bin' },
// { from: `${SRC}images/favicon.png` },
// { from: `${SRC}images` },
]),
diff --git a/webpack/webpack.config.prod.babel.js b/webpack/webpack.config.prod.babel.js
index 1d02592c..22afaf0a 100644
--- a/webpack/webpack.config.prod.babel.js
+++ b/webpack/webpack.config.prod.babel.js
@@ -1,4 +1,4 @@
-import { SRC, BUILD, TREZOR_LIBRARY, TREZOR_CONNECT_FILES } from './constants';
+import { SRC, BUILD, TREZOR_LIBRARY, TREZOR_CONNECT_FILES, TREZOR_CONNECT_HTML } from './constants';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
@@ -12,7 +12,7 @@ const extractLess = new ExtractTextPlugin({
module.exports = {
entry: {
index: ['whatwg-fetch', `${SRC}js/index.js`],
- 'trezor-library': `${TREZOR_LIBRARY}.js`
+ //'trezor-library': `${TREZOR_LIBRARY}.js`
},
output: {
filename: 'js/[name].[hash].js',
@@ -47,17 +47,26 @@ module.exports = {
},
{
test: /\.(png|gif|jpg)$/,
- loader: 'file-loader?name=../images/[name].[ext]'
+ loader: 'file-loader',
+ query: {
+ publicPath: '../',
+ name: 'images/[name].[hash].[ext]',
+ }
},
{
test: /\.(ttf|eot|svg|woff|woff2)$/,
- loader: 'file-loader?publicPath=../&name=fonts/[name].[ext]',
+ // loader: 'file-loader?publicPath=../&name=fonts/[name].[hash].[ext]',
+ loader: 'file-loader',
+ query: {
+ publicPath: '../',
+ name: 'fonts/[name].[hash].[ext]',
+ }
},
{
test: /\.(wasm)$/,
loader: 'file-loader',
query: {
- name: 'js/[name].[ext]',
+ name: 'js/[name].[hash].[ext]',
},
},
{
@@ -88,8 +97,11 @@ module.exports = {
//{from: `${SRC}/app/robots.txt`},
//{ from: `${SRC}js/vendor`, to: `${BUILD}js/vendor` },
//{ from: `${SRC}config.json` },
- { from: `${SRC}images`, to: `${BUILD}images` },
- { from: `${SRC}data`, to: `${BUILD}data` },
+ //{ from: `${SRC}images/favicon.png`, to: `${BUILD}favicon.png` },
+ { from: `${SRC}images/favicon.ico`, to: `${BUILD}favicon.ico` },
+ { from: `${SRC}images/favicon.png`, to: `${BUILD}favicon.png` },
+ { from: `${SRC}images/dashboard.png`, to: `${BUILD}images/dashboard.png` },
+ { from: `${SRC}data`, to: `${BUILD}data`, cache: false },
]),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
@@ -99,10 +111,11 @@ module.exports = {
// }
// }),
new CopyWebpackPlugin([
- { from: `${TREZOR_CONNECT_FILES}coins.json` },
- { from: `${TREZOR_CONNECT_FILES}releases.json` },
- { from: `${TREZOR_CONNECT_FILES}latest.txt` },
- { from: `${TREZOR_CONNECT_FILES}config_signed.bin` },
+ { from: `${TREZOR_CONNECT_FILES}coins.json`, to: `${BUILD}/data/coins.json` },
+ { from: `${TREZOR_CONNECT_FILES}releases-1.json`, to: `${BUILD}/data/releases-1.json` },
+ { from: `${TREZOR_CONNECT_FILES}releases-2.json`, to: `${BUILD}/data/releases-2.json` },
+ { from: `${TREZOR_CONNECT_FILES}latest.txt`, to: `${BUILD}/data/latest.txt` },
+ { from: `${TREZOR_CONNECT_FILES}config_signed.bin`, to: `${BUILD}/data/config_signed.bin` },
]),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
diff --git a/yarn.lock b/yarn.lock
index 110f1adf..e21cde443 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -33,9 +33,9 @@ add-dom-event-listener@1.x:
dependencies:
object-assign "4.x"
-ajv-keywords@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
+ajv-keywords@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be"
ajv@^4.9.1:
version "4.11.8"
@@ -44,7 +44,7 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
-ajv@^5.0.0, ajv@^5.1.5:
+ajv@^5.0.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.4.0.tgz#32d1cf08dbc80c432f426f12e10b2511f6b46474"
dependencies:
@@ -53,6 +53,14 @@ ajv@^5.0.0, ajv@^5.1.5:
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
+ajv@^6.1.0:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.1.1.tgz#978d597fbc2b7d0e5a5c3ddeb149a682f2abfa0e"
+ dependencies:
+ fast-deep-equal "^1.0.0"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.3.0"
+
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@@ -81,7 +89,7 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
-ansi-styles@^3.1.0:
+ansi-styles@^3.1.0, ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
@@ -94,7 +102,7 @@ anymatch@^1.3.0:
micromatch "^2.1.5"
normalize-path "^2.0.0"
-aproba@^1.0.3:
+aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -121,14 +129,32 @@ arr-flatten@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
+array-find-index@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+array-union@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+ dependencies:
+ array-uniq "^1.0.1"
+
+array-uniq@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+arrify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
asap@~2.0.3:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
@@ -213,7 +239,7 @@ babel-cli@^6.24.1:
optionalDependencies:
chokidar "^1.6.1"
-babel-code-frame@^6.11.0, babel-code-frame@^6.26.0:
+babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
dependencies:
@@ -884,7 +910,7 @@ bluebird@^3.4.7, bluebird@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.3, bn.js@^4.4.0, bn.js@^4.8.0:
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.4.0, bn.js@^4.8.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
@@ -913,6 +939,10 @@ boom@2.x.x:
dependencies:
hoek "2.x.x"
+bowser@^1.9.2:
+ version "1.9.2"
+ resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.2.tgz#d66fc868ca5f4ba895bee1363c343fe7b37d3394"
+
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
@@ -1026,6 +1056,24 @@ bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+cacache@^10.0.1:
+ version "10.0.4"
+ resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460"
+ dependencies:
+ bluebird "^3.5.1"
+ chownr "^1.0.1"
+ glob "^7.1.2"
+ graceful-fs "^4.1.11"
+ lru-cache "^4.1.1"
+ mississippi "^2.0.0"
+ mkdirp "^0.5.1"
+ move-concurrently "^1.0.1"
+ promise-inflight "^1.0.1"
+ rimraf "^2.6.2"
+ ssri "^5.2.4"
+ unique-filename "^1.1.0"
+ y18n "^4.0.0"
+
camel-case@3.0.x:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
@@ -1083,6 +1131,14 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
+chalk@^2.0.1, chalk@^2.1.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796"
+ dependencies:
+ ansi-styles "^3.2.0"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.2.0"
+
chalk@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
@@ -1106,6 +1162,10 @@ chokidar@^1.6.1, chokidar@^1.7.0:
optionalDependencies:
fsevents "^1.0.0"
+chownr@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181"
+
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -1145,6 +1205,14 @@ cliui@^3.2.0:
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
+cliui@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc"
+ dependencies:
+ string-width "^2.1.1"
+ strip-ansi "^4.0.0"
+ wrap-ansi "^2.0.0"
+
clone@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
@@ -1246,6 +1314,14 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+concat-stream@^1.5.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
+ dependencies:
+ inherits "^2.0.3"
+ readable-stream "^2.2.2"
+ typedarray "^0.0.6"
+
console-browserify@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
@@ -1280,16 +1356,29 @@ cookie@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
-copy-webpack-plugin@^4.0.1:
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.2.3.tgz#4a3c61089f3b635777f0f0af346c338b39d63755"
+copy-concurrently@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
dependencies:
- bluebird "^3.5.1"
- glob "^7.1.2"
+ aproba "^1.1.1"
+ fs-write-stream-atomic "^1.0.8"
+ iferr "^0.1.5"
+ mkdirp "^0.5.1"
+ rimraf "^2.5.4"
+ run-queue "^1.0.0"
+
+copy-webpack-plugin@^4.4.1:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.4.1.tgz#1e8c366211db6dc2ddee40e5a3e4fc661dd149e8"
+ dependencies:
+ cacache "^10.0.1"
+ find-cache-dir "^1.0.0"
+ globby "^7.1.1"
is-glob "^4.0.0"
loader-utils "^0.2.15"
- lodash "^4.3.0"
minimatch "^3.0.4"
+ p-limit "^1.0.0"
+ serialize-javascript "^1.4.0"
core-js@^1.0.0:
version "1.2.7"
@@ -1383,22 +1472,22 @@ css-color-names@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
-css-loader@^0.28.4:
- version "0.28.7"
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
+css-loader@^0.28.9:
+ version "0.28.9"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.9.tgz#68064b85f4e271d7ce4c48a58300928e535d1c95"
dependencies:
- babel-code-frame "^6.11.0"
+ babel-code-frame "^6.26.0"
css-selector-tokenizer "^0.7.0"
- cssnano ">=2.6.1 <4"
+ cssnano "^3.10.0"
icss-utils "^2.1.0"
loader-utils "^1.0.2"
lodash.camelcase "^4.3.0"
- object-assign "^4.0.1"
+ object-assign "^4.1.1"
postcss "^5.0.6"
- postcss-modules-extract-imports "^1.0.0"
- postcss-modules-local-by-default "^1.0.1"
- postcss-modules-scope "^1.0.0"
- postcss-modules-values "^1.1.0"
+ postcss-modules-extract-imports "^1.2.0"
+ postcss-modules-local-by-default "^1.2.0"
+ postcss-modules-scope "^1.1.0"
+ postcss-modules-values "^1.3.0"
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"
@@ -1427,7 +1516,7 @@ cssesc@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
-"cssnano@>=2.6.1 <4":
+cssnano@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38"
dependencies:
@@ -1471,6 +1560,16 @@ csso@~2.3.1:
clap "^1.0.9"
source-map "^0.5.3"
+currently-unhandled@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
+ dependencies:
+ array-find-index "^1.0.1"
+
+cyclist@~0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
+
d@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
@@ -1550,6 +1649,13 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
+dir-glob@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
+ dependencies:
+ arrify "^1.0.1"
+ path-type "^3.0.0"
+
dom-align@1.x:
version "1.6.7"
resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.6.7.tgz#6858138efb6b77405ce99146d0be5e4f7282813f"
@@ -1614,6 +1720,15 @@ drbg.js@^1.0.1:
create-hash "^1.1.2"
create-hmac "^1.1.4"
+duplexify@^3.4.2, duplexify@^3.5.3:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.3.tgz#8b5818800df92fd0125b27ab896491912858243e"
+ dependencies:
+ end-of-stream "^1.0.0"
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+ stream-shift "^1.0.0"
+
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@@ -1654,6 +1769,12 @@ encoding@^0.1.11:
dependencies:
iconv-lite "~0.4.13"
+end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
+ dependencies:
+ once "^1.4.0"
+
enhanced-resolve@^3.4.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
@@ -1794,7 +1915,7 @@ ethereumjs-units@^0.2.0:
dependencies:
bignumber.js "^2.3.0"
-ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.2:
+ethereumjs-util@^5.0.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.2.tgz#25ba0215cbb4c2f0b108a6f96af2a2e62e45921f"
dependencies:
@@ -1807,6 +1928,18 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.2:
rlp "^2.0.0"
secp256k1 "^3.0.1"
+ethereumjs-util@^5.1.4:
+ version "5.1.4"
+ resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.1.4.tgz#d1a4a9be31eaf8b33aad399894f854fdafda2469"
+ dependencies:
+ bn.js "^4.11.0"
+ create-hash "^1.1.2"
+ ethjs-util "^0.1.3"
+ keccak "^1.0.2"
+ rlp "^2.0.0"
+ safe-buffer "^5.1.1"
+ secp256k1 "^3.0.1"
+
ethjs-util@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.4.tgz#1c8b6879257444ef4d3f3fbbac2ded12cd997d93"
@@ -1938,11 +2071,12 @@ fbjs@^0.8.16, fbjs@^0.8.9:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"
-file-loader@^0.11.2:
- version "0.11.2"
- resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.2.tgz#4ff1df28af38719a6098093b88c82c71d1794a34"
+file-loader@^1.1.9:
+ version "1.1.9"
+ resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.9.tgz#cf152aedbcfb3d67038d0845efb7cf11a96e53de"
dependencies:
loader-utils "^1.0.2"
+ schema-utils "^0.4.5"
filename-regex@^2.0.0:
version "2.0.1"
@@ -1988,6 +2122,13 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
+flush-write-stream@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.4"
+
for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -2018,10 +2159,26 @@ fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+from2@^2.1.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
+ dependencies:
+ inherits "^2.0.1"
+ readable-stream "^2.0.0"
+
fs-readdir-recursive@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
+fs-write-stream-atomic@^1.0.8:
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
+ dependencies:
+ graceful-fs "^4.1.2"
+ iferr "^0.1.5"
+ imurmurhash "^0.1.4"
+ readable-stream "1 || 2"
+
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -2116,7 +2273,18 @@ globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
-graceful-fs@^4.1.2, graceful-fs@^4.1.4:
+globby@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680"
+ dependencies:
+ array-union "^1.0.1"
+ dir-glob "^2.0.0"
+ glob "^7.1.2"
+ ignore "^3.3.5"
+ pify "^3.0.0"
+ slash "^1.0.0"
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
@@ -2145,6 +2313,10 @@ has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -2184,11 +2356,12 @@ hawk@3.1.3, hawk@~3.1.3:
hoek "2.x.x"
sntp "1.x.x"
-hdkey@0.7.1:
- version "0.7.1"
- resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.7.1.tgz#caee4be81aa77921e909b8d228dd0f29acaee632"
+hdkey@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.8.0.tgz#08c9a9fcb6a42d9724d669f81c53a3c507f87bf1"
dependencies:
coinstring "^2.0.0"
+ safe-buffer "^5.1.1"
secp256k1 "^3.0.1"
he@1.1.x:
@@ -2217,10 +2390,14 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
-hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.3.0:
+hoist-non-react-statics@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
+hoist-non-react-statics@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40"
+
home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
@@ -2312,10 +2489,22 @@ ieee754@^1.1.4:
version "1.1.8"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4"
+iferr@^0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
+
+ignore@^3.3.5:
+ version "3.3.7"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021"
+
image-size@~0.5.0:
version "0.5.5"
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+
indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
@@ -2611,14 +2800,14 @@ less-loader@^4.0.5:
loader-utils "^1.1.0"
pify "^2.3.0"
-less@^2.7.2:
- version "2.7.3"
- resolved "https://registry.yarnpkg.com/less/-/less-2.7.3.tgz#cc1260f51c900a9ec0d91fb6998139e02507b63b"
+less@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/less/-/less-3.0.1.tgz#ba2fea24a5632ccb8c84230d6043c0bf91855e37"
optionalDependencies:
errno "^0.1.1"
graceful-fs "^4.1.2"
image-size "~0.5.0"
- mime "^1.2.11"
+ mime "^1.4.1"
mkdirp "^0.5.0"
promise "^7.1.1"
request "2.81.0"
@@ -2661,7 +2850,11 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"
-lodash-es@^4.2.0, lodash-es@^4.2.1:
+lodash-es@^4.17.5:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.5.tgz#9fc6e737b1c4d151d8f9cae2247305d552ce748f"
+
+lodash-es@^4.2.1:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7"
@@ -2718,10 +2911,24 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-lodash@^4.14.0, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1:
+lodash@^4.14.0, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.6.1:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+lodash@^4.17.5:
+ version "4.17.5"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
+
+log-symbols@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
+ dependencies:
+ chalk "^2.0.1"
+
+loglevelnext@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-1.0.3.tgz#0f69277e73bbbf2cd61b94d82313216bf87ac66e"
+
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -2732,11 +2939,18 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
dependencies:
js-tokens "^3.0.0"
+loud-rejection@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
+ dependencies:
+ currently-unhandled "^0.4.1"
+ signal-exit "^3.0.0"
+
lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
-lru-cache@^4.0.1:
+lru-cache@^4.0.1, lru-cache@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55"
dependencies:
@@ -2828,9 +3042,13 @@ mime@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
-mime@^1.2.11, mime@^1.4.1:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/mime/-/mime-1.5.0.tgz#59c20e03ae116089edeb7d3b34a6788c5b3cccea"
+mime@^1.4.1:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+
+mime@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b"
mimic-fn@^1.0.0:
version "1.1.0"
@@ -2864,12 +3082,38 @@ minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+mississippi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f"
+ dependencies:
+ concat-stream "^1.5.0"
+ duplexify "^3.4.2"
+ end-of-stream "^1.1.0"
+ flush-write-stream "^1.0.0"
+ from2 "^2.1.0"
+ parallel-transform "^1.1.0"
+ pump "^2.0.1"
+ pumpify "^1.3.3"
+ stream-each "^1.1.0"
+ through2 "^2.0.0"
+
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
+move-concurrently@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
+ dependencies:
+ aproba "^1.1.1"
+ copy-concurrently "^1.0.0"
+ fs-write-stream-atomic "^1.0.8"
+ mkdirp "^0.5.1"
+ rimraf "^2.5.4"
+ run-queue "^1.0.3"
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -3030,7 +3274,7 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
-once@^1.3.0, once@^1.3.3:
+once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
@@ -3079,6 +3323,12 @@ p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+p-limit@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c"
+ dependencies:
+ p-try "^1.0.0"
+
p-limit@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
@@ -3089,10 +3339,22 @@ p-locate@^2.0.0:
dependencies:
p-limit "^1.1.0"
+p-try@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
+
pako@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
+parallel-transform@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06"
+ dependencies:
+ cyclist "~0.2.2"
+ inherits "^2.0.3"
+ readable-stream "^2.1.5"
+
param-case@2.1.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
@@ -3164,6 +3426,12 @@ path-type@^2.0.0:
dependencies:
pify "^2.0.0"
+path-type@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
+ dependencies:
+ pify "^3.0.0"
+
pbkdf2@^3.0.3:
version "3.0.14"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade"
@@ -3318,27 +3586,27 @@ postcss-minify-selectors@^2.0.4:
postcss "^5.0.14"
postcss-selector-parser "^2.0.0"
-postcss-modules-extract-imports@^1.0.0:
+postcss-modules-extract-imports@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85"
dependencies:
postcss "^6.0.1"
-postcss-modules-local-by-default@^1.0.1:
+postcss-modules-local-by-default@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
dependencies:
css-selector-tokenizer "^0.7.0"
postcss "^6.0.1"
-postcss-modules-scope@^1.0.0:
+postcss-modules-scope@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
dependencies:
css-selector-tokenizer "^0.7.0"
postcss "^6.0.1"
-postcss-modules-values@^1.1.0:
+postcss-modules-values@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
dependencies:
@@ -3465,6 +3733,10 @@ process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+process-nextick-args@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
+
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
@@ -3473,6 +3745,10 @@ process@~0.5.1:
version "0.5.2"
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
+promise-inflight@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
+
promise@^7.1.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
@@ -3512,6 +3788,21 @@ public-encrypt@^4.0.0:
parse-asn1 "^5.0.0"
randombytes "^2.0.1"
+pump@^2.0.0, pump@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
+ dependencies:
+ end-of-stream "^1.1.0"
+ once "^1.3.1"
+
+pumpify@^1.3.3:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.4.0.tgz#80b7c5df7e24153d03f0e7ac8a05a5d068bd07fb"
+ dependencies:
+ duplexify "^3.5.3"
+ inherits "^2.0.3"
+ pump "^2.0.0"
+
punycode@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
@@ -3581,6 +3872,10 @@ range-parser@^1.0.3, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
+raven-js@^3.1.1, raven-js@^3.22.3:
+ version "3.22.3"
+ resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.22.3.tgz#8330dcc102b699ffbc2f48790978b997bf4d8f75"
+
raw-body@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
@@ -3669,7 +3964,7 @@ react-dom@^15.4.1:
object-assign "^4.1.0"
prop-types "^15.5.10"
-"react-dom@^15.4.2 || ^16.0.0":
+"react-dom@^15.4.2 || ^16.0.0", react-dom@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
dependencies:
@@ -3678,15 +3973,6 @@ react-dom@^15.4.1:
object-assign "^4.1.1"
prop-types "^15.6.0"
-react-dom@^16.1.1:
- version "16.1.1"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.1.1.tgz#b2e331b6d752faf1a2d31399969399a41d8d45f8"
- dependencies:
- fbjs "^0.8.16"
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- prop-types "^15.6.0"
-
react-ellipsis-text@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/react-ellipsis-text/-/react-ellipsis-text-1.0.0.tgz#98ac5d4e1a2b21e7f76e49f5f23ce65c99f74590"
@@ -3704,9 +3990,9 @@ react-hot-loader@^3.1.3:
redbox-react "^1.3.6"
source-map "^0.6.1"
-react-input-autosize@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.1.2.tgz#a3dc11a5517c434db25229925541309de3f7a8f5"
+react-input-autosize@^2.1.2:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8"
dependencies:
prop-types "^15.5.8"
@@ -3723,16 +4009,16 @@ react-qr-svg@^2.1.0:
prop-types "^15.5.8"
qr.js "0.0.0"
-react-redux@^5.0.6:
- version "5.0.6"
- resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946"
+react-redux@^5.0.7:
+ version "5.0.7"
+ resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
dependencies:
- hoist-non-react-statics "^2.2.1"
+ hoist-non-react-statics "^2.5.0"
invariant "^2.0.0"
- lodash "^4.2.0"
- lodash-es "^4.2.0"
+ lodash "^4.17.5"
+ lodash-es "^4.17.5"
loose-envify "^1.1.0"
- prop-types "^15.5.10"
+ prop-types "^15.6.0"
react-router-dom@^4.2.2:
version "4.2.2"
@@ -3776,13 +4062,13 @@ react-scale-text@^1.2.2:
shortid "^2.2.8"
warning "^3.0.0"
-react-select@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.1.0.tgz#626a2de839fdea2ade74dd1b143a9bde34be6c82"
+react-select@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.2.1.tgz#a2fe58a569eb14dcaa6543816260b97e538120d1"
dependencies:
classnames "^2.2.4"
prop-types "^15.5.8"
- react-input-autosize "^2.1.0"
+ react-input-autosize "^2.1.2"
react-transition-group@^1.0.0:
version "1.2.1"
@@ -3815,7 +4101,7 @@ react@^15.4.1:
object-assign "^4.1.0"
prop-types "^15.5.10"
-"react@^15.4.2 || ^16.0.0":
+"react@^15.4.2 || ^16.0.0", react@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
dependencies:
@@ -3824,15 +4110,6 @@ react@^15.4.1:
object-assign "^4.1.1"
prop-types "^15.6.0"
-react@^16.1.1:
- version "16.1.1"
- resolved "https://registry.yarnpkg.com/react/-/react-16.1.1.tgz#d5c4ef795507e3012282dd51261ff9c0e824fe1f"
- dependencies:
- fbjs "^0.8.16"
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- prop-types "^15.6.0"
-
read-pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
@@ -3848,6 +4125,18 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
+"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.4, readable-stream@^2.1.5, readable-stream@^2.2.2:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.4.tgz#c946c3f47fa7d8eabc0b6150f4a12f69a4574071"
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.0.3"
+ util-deprecate "~1.0.1"
+
readable-stream@1.0:
version "1.0.34"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
@@ -3913,6 +4202,12 @@ redux-logger@^3.0.6:
dependencies:
deep-diff "^0.3.5"
+redux-raven-middleware@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/redux-raven-middleware/-/redux-raven-middleware-1.2.0.tgz#50d02dd653cf93d2df18c4652149f1009bbbe33d"
+ dependencies:
+ raven-js "^3.1.1"
+
redux-thunk@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5"
@@ -4055,7 +4350,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
+rimraf@2, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@@ -4072,6 +4367,12 @@ rlp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0"
+run-queue@^1.0.0, run-queue@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
+ dependencies:
+ aproba "^1.1.1"
+
safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@@ -4086,6 +4387,13 @@ schema-utils@^0.3.0:
dependencies:
ajv "^5.0.0"
+schema-utils@^0.4.3, schema-utils@^0.4.5:
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e"
+ dependencies:
+ ajv "^6.1.0"
+ ajv-keywords "^3.1.0"
+
secp256k1@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.4.0.tgz#1c905b256fa4ae5b9cc170e672dd59b4c5de46a4"
@@ -4121,6 +4429,10 @@ send@0.16.1:
range-parser "~1.2.0"
statuses "~1.3.1"
+serialize-javascript@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005"
+
serve-static@1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719"
@@ -4257,6 +4569,12 @@ sshpk@^1.7.0:
jsbn "~0.1.0"
tweetnacl "~0.14.0"
+ssri@^5.2.4:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.2.4.tgz#9985e14041e65fc397af96542be35724ac11da52"
+ dependencies:
+ safe-buffer "^5.1.1"
+
stackframe@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4"
@@ -4276,6 +4594,13 @@ stream-browserify@^2.0.1:
inherits "~2.0.1"
readable-stream "^2.0.2"
+stream-each@^1.1.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd"
+ dependencies:
+ end-of-stream "^1.1.0"
+ stream-shift "^1.0.0"
+
stream-http@^2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad"
@@ -4286,6 +4611,10 @@ stream-http@^2.7.2:
to-arraybuffer "^1.0.0"
xtend "^4.0.0"
+stream-shift@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
+
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@@ -4298,7 +4627,7 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
-string-width@^2.0.0:
+string-width@^2.0.0, string-width@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
dependencies:
@@ -4349,12 +4678,12 @@ strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
-style-loader@^0.18.2:
- version "0.18.2"
- resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.2.tgz#cc31459afbcd6d80b7220ee54b291a9fd66ff5eb"
+style-loader@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.20.2.tgz#851b373c187890331776e9cde359eea9c95ecd00"
dependencies:
- loader-utils "^1.0.2"
- schema-utils "^0.3.0"
+ loader-utils "^1.1.0"
+ schema-utils "^0.4.3"
supports-color@^2.0.0:
version "2.0.0"
@@ -4372,6 +4701,12 @@ supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0:
dependencies:
has-flag "^2.0.0"
+supports-color@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a"
+ dependencies:
+ has-flag "^3.0.0"
+
svgo@^0.7.0:
version "0.7.2"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"
@@ -4413,9 +4748,12 @@ tar@^2.2.1:
fstream "^1.0.2"
inherits "2"
-time-stamp@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357"
+through2@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
+ dependencies:
+ readable-stream "^2.1.5"
+ xtend "~4.0.1"
timers-browserify@^2.0.4:
version "2.0.4"
@@ -4466,6 +4804,10 @@ type-is@~1.6.15:
media-typer "0.3.0"
mime-types "~2.1.15"
+typedarray@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+
ua-parser-js@^0.7.9:
version "0.7.17"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
@@ -4516,6 +4858,18 @@ uniqs@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
+unique-filename@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3"
+ dependencies:
+ unique-slug "^2.0.0"
+
+unique-slug@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab"
+ dependencies:
+ imurmurhash "^0.1.4"
+
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -4524,6 +4878,10 @@ upper-case@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
+url-join@^2.0.2:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728"
+
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -4565,6 +4923,10 @@ uuid@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
+uuid@^3.1.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
+
v8flags@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
@@ -4628,25 +4990,36 @@ web3@^0.19.0:
xhr2 "*"
xmlhttprequest "*"
-webpack-dev-middleware@^1.11.0:
- version "1.12.1"
- resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.1.tgz#338be3ca930973be1c2ce07d84d275e997e1a25a"
+webpack-dev-middleware@2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-2.0.5.tgz#2a1d07afb599e1993033d72c2181ec2344c15e31"
dependencies:
+ loud-rejection "^1.6.0"
memory-fs "~0.4.1"
- mime "^1.4.1"
+ mime "^2.1.0"
path-is-absolute "^1.0.0"
range-parser "^1.0.3"
- time-stamp "^2.0.0"
+ url-join "^2.0.2"
+ webpack-log "^1.0.1"
-webpack-hot-middleware@^2.18.0:
- version "2.20.0"
- resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.20.0.tgz#cb896d837758b6408fe0afeeafdc0e5316b15319"
+webpack-hot-middleware@2.21.0:
+ version "2.21.0"
+ resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.21.0.tgz#7b3c113a7a4b301c91e0749573c7aab28b414b52"
dependencies:
ansi-html "0.0.7"
html-entities "^1.2.0"
querystring "^0.2.0"
strip-ansi "^3.0.0"
+webpack-log@^1.0.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.1.2.tgz#cdc76016537eed24708dc6aa3d1e52189efee107"
+ dependencies:
+ chalk "^2.1.0"
+ log-symbols "^2.1.0"
+ loglevelnext "^1.0.1"
+ uuid "^3.1.0"
+
webpack-merge@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.1.tgz#f1197a0a973e69c6fbeeb6d658219aa8c0c13555"
@@ -4660,14 +5033,14 @@ webpack-sources@^1.0.1:
source-list-map "^2.0.0"
source-map "~0.6.1"
-webpack@^3.4.1:
- version "3.8.1"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.8.1.tgz#b16968a81100abe61608b0153c9159ef8bb2bd83"
+webpack@3.11.0:
+ version "3.11.0"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894"
dependencies:
acorn "^5.0.0"
acorn-dynamic-import "^2.0.0"
- ajv "^5.1.5"
- ajv-keywords "^2.0.0"
+ ajv "^6.1.0"
+ ajv-keywords "^3.1.0"
async "^2.1.2"
enhanced-resolve "^3.4.0"
escope "^3.6.0"
@@ -4742,7 +5115,7 @@ xmlhttprequest@*:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"
-xtend@^4.0.0:
+xtend@^4.0.0, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
@@ -4750,6 +5123,10 @@ y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
+y18n@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
+
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
@@ -4760,17 +5137,17 @@ yargs-parser@^7.0.0:
dependencies:
camelcase "^4.1.0"
-yargs-parser@^8.0.0:
- version "8.0.0"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6"
+yargs-parser@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
dependencies:
camelcase "^4.1.0"
-yargs@^10.0.3:
- version "10.0.3"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae"
+yargs@11.0.0:
+ version "11.0.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.0.0.tgz#c052931006c5eee74610e5fc0354bedfd08a201b"
dependencies:
- cliui "^3.2.0"
+ cliui "^4.0.0"
decamelize "^1.1.1"
find-up "^2.1.0"
get-caller-file "^1.0.1"
@@ -4781,7 +5158,7 @@ yargs@^10.0.3:
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
- yargs-parser "^8.0.0"
+ yargs-parser "^9.0.2"
yargs@^8.0.2:
version "8.0.2"