From 17d50eaf873f61bdc776b2ab96e612fa40de46fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Mon, 29 Jan 2018 15:54:11 +0100 Subject: [PATCH 1/2] Re-use legder API --- package.json | 1 - src/components/TransactionsList/index.js | 8 ++- src/components/TransactionsList/stories.js | 4 +- src/helpers/btc.js | 40 +++++---------- src/reducers/accounts.js | 2 +- src/types/common.js | 2 +- yarn.lock | 58 ++-------------------- 7 files changed, 25 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index 11d77a68..8438abce 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "axios": "^0.17.1", "bcryptjs": "^2.4.3", "bitcoinjs-lib": "^3.3.2", - "blockchain.info": "^2.11.0", "bs58check": "^2.1.1", "color": "^3.0.0", "cross-env": "^5.1.3", diff --git a/src/components/TransactionsList/index.js b/src/components/TransactionsList/index.js index 5e25cc6b..52d26f4d 100644 --- a/src/components/TransactionsList/index.js +++ b/src/components/TransactionsList/index.js @@ -23,8 +23,6 @@ const Cap = styled(Text).attrs({ letter-spacing: 1px; ` -const Body = styled(Box)`` - const HeaderCol = ({ size, children, ...props }: { size?: number, children: any }) => ( {children} @@ -54,7 +52,7 @@ const Cell = styled(Box).attrs({ ` const Transaction = ({ tx }: { tx: TransactionType }) => { - const time = moment(tx.time * 1e3) + const time = moment(tx.received_at) return ( @@ -74,7 +72,7 @@ const Transaction = ({ tx }: { tx: TransactionType }) => { display: 'block', }} > - {tx.balance > 0 ? get(tx, 'inputs.0.prev_out.addr') : get(tx, 'out.0.addr')} + {tx.balance > 0 ? get(tx, 'inputs.0.address') : get(tx, 'outputs.0.address')} 0 ? 'green' : void 0}>{formatBTC(tx.balance)} @@ -92,6 +90,6 @@ export default ({ transactions }: { transactions: Array }) => ( {'Amount'} - {transactions.map(t => )} + {transactions.map(t => )} ) diff --git a/src/components/TransactionsList/stories.js b/src/components/TransactionsList/stories.js index 9463f508..a6248474 100644 --- a/src/components/TransactionsList/stories.js +++ b/src/components/TransactionsList/stories.js @@ -11,12 +11,12 @@ const transactions = [ { hash: '5c6ea1716520c7d6e038d36a3223faced3c4b8f7ffb69d9fb5bd527d562fdb62', balance: 130000000, - time: 1516809771, + received_at: '2018-01-09T16:03:52Z', }, { hash: '27416a48caab90fab053b507b8b6b9d48fba75421d3bfdbae4b85f64024bc9c4', balance: 65000000, - time: 1516704444, + received_at: '2018-01-09T16:02:40Z', }, ] diff --git a/src/helpers/btc.js b/src/helpers/btc.js index b1596ae6..ba760279 100644 --- a/src/helpers/btc.js +++ b/src/helpers/btc.js @@ -1,10 +1,8 @@ // @flow -// import axios from 'axios' +import axios from 'axios' import bitcoin from 'bitcoinjs-lib' -const blockexplorer = require('blockchain.info/blockexplorer').usingNetwork(3) - export const networks = [ { ...bitcoin.networks.bitcoin, @@ -17,26 +15,13 @@ export const networks = [ ] export function computeTransaction(addresses: Array<*>) { - // return (transaction: Object) => { - // const outputVal = transaction.outputs - // .filter(o => addresses.includes(o.address)) - // .reduce((acc, cur) => acc + cur.value, 0) - // const inputVal = transaction.inputs - // .filter(i => addresses.includes(i.address)) - // .reduce((acc, cur) => acc + cur.value, 0) - // const balance = outputVal - inputVal - // return { - // ...transaction, - // balance, - // } - // } return (transaction: Object) => { - const outputVal = transaction.out - .filter(o => addresses.includes(o.addr)) + const outputVal = transaction.outputs + .filter(o => addresses.includes(o.address)) .reduce((acc, cur) => acc + cur.value, 0) const inputVal = transaction.inputs - .filter(i => addresses.includes(i.prev_out.addr)) - .reduce((acc, cur) => acc + cur.prev_out.value, 0) + .filter(i => addresses.includes(i.address)) + .reduce((acc, cur) => acc + cur.value, 0) const balance = outputVal - inputVal return { ...transaction, @@ -46,12 +31,13 @@ export function computeTransaction(addresses: Array<*>) { } export function getTransactions(addresses: Array) { - // return axios.get( - // `http://api.ledgerwallet.com/blockchain/v2/btc_testnet/addresses/${addresses.join( - // ',', - // )}/transactions?noToken=true`, - // ) - return blockexplorer.getMultiAddress(addresses) + return axios + .get( + `http://api.ledgerwallet.com/blockchain/v2/btc_testnet/addresses/${addresses.join( + ',', + )}/transactions?noToken=true`, + ) + .then(({ data }) => data) } export async function getAccount({ @@ -104,7 +90,7 @@ export async function getAccount({ new Promise(resolve => setTimeout(() => resolve(getAddress(params)), asyncDelay)) const getLastAddress = (addresses, txs) => { - const txsAddresses = [...txs.inputs.map(tx => tx.prev_out.addr), ...txs.out.map(tx => tx.addr)] + const txsAddresses = [...txs.inputs.map(tx => tx.address), ...txs.outputs.map(tx => tx.address)] const lastAddress = addresses.reverse().find(a => txsAddresses.includes(a.address)) || { index: 0, } diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js index b3a5b099..c6cfc5d7 100644 --- a/src/reducers/accounts.js +++ b/src/reducers/accounts.js @@ -17,7 +17,7 @@ const state: AccountsState = {} function getAccount(account: Account) { const transactions = get(account.data, 'transactions', []) - transactions.sort((a, b) => b.time - a.time) + transactions.sort((a, b) => new Date(b.received_at) - new Date(a.received_at)) return { ...account, diff --git a/src/types/common.js b/src/types/common.js index 0d41c713..69183ecd 100644 --- a/src/types/common.js +++ b/src/types/common.js @@ -13,7 +13,7 @@ export type Devices = Array export type Transaction = { balance: number, hash: string, - time: number, + received_at: string, } // -------------------- Accounts diff --git a/yarn.lock b/yarn.lock index 834b63f7..ba01f07c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1803,28 +1803,12 @@ block-stream@*: dependencies: inherits "~2.0.0" -blockchain.info@^2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/blockchain.info/-/blockchain.info-2.11.0.tgz#63b46617e194164d377e183e6c667d3ef38ad5b6" - dependencies: - q "^1.4.1" - request-promise "^0.4.3" - url-join "0.0.1" - url-parse "^1.0.5" - url-pattern "^0.10.2" - optionalDependencies: - ws "^1.1.2" - bluebird-lst@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.5.tgz#bebc83026b7e92a72871a3dc599e219cbfb002a9" dependencies: bluebird "^3.5.1" -bluebird@^2.3: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -2217,7 +2201,7 @@ chalk@0.5.1: strip-ansi "^0.3.0" supports-color "^0.2.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -5687,7 +5671,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^3.10.0, lodash@^3.10.1: +lodash@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -6388,10 +6372,6 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" @@ -7165,7 +7145,7 @@ pushdata-bitcoin@^1.0.1: dependencies: bitcoin-ops "^1.3.0" -q@^1.1.2, q@^1.4.1: +q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -7792,15 +7772,6 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request-promise@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-0.4.3.tgz#3c8ddc82f06f8908d720aede1d6794258e22121c" - dependencies: - bluebird "^2.3" - chalk "^1.1.0" - lodash "^3.10.0" - request "^2.34" - request@2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" @@ -7828,7 +7799,7 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@^2.34, request@^2.45.0, request@^2.81.0, request@^2.83.0: +request@^2.45.0, request@^2.81.0, request@^2.83.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -8939,10 +8910,6 @@ uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" @@ -9040,10 +9007,6 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" -url-join@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/url-join/-/url-join-0.0.1.tgz#1db48ad422d3402469a87f7d97bdebfe4fb1e3c8" - url-loader@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.6.2.tgz#a007a7109620e9d988d14bce677a1decb9a993f7" @@ -9065,17 +9028,13 @@ url-parse@1.0.x: querystringify "0.0.x" requires-port "1.0.x" -url-parse@^1.0.5, url-parse@^1.1.8: +url-parse@^1.1.8: version "1.2.0" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.2.0.tgz#3a19e8aaa6d023ddd27dcc44cb4fc8f7fec23986" dependencies: querystringify "~1.0.0" requires-port "~1.0.0" -url-pattern@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/url-pattern/-/url-pattern-0.10.2.tgz#e9f07104982b72312db4473dd86a527b580015da" - url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" @@ -9403,13 +9362,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" - dependencies: - options ">=0.0.5" - ultron "1.0.x" - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From c0f80baac7a4485cb800e0c8adf89396e107e54b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Mon, 29 Jan 2018 18:36:31 +0100 Subject: [PATCH 2/2] Add Send, Receive and Options button in Account page --- package.json | 6 +-- src/components/AccountPage.js | 54 ++++++++++++++++++++--- src/components/DashboardPage.js | 8 ++-- src/components/SideBar/Item.js | 20 ++------- src/components/SideBar/index.js | 8 ++-- src/components/base/Button/index.js | 53 +++++++++++++++++----- src/components/base/Modal/index.js | 8 ++-- src/components/modals/AddAccount/index.js | 4 +- src/components/modals/Receive.js | 25 +++++++++-- src/components/modals/Send.js | 18 +++++--- src/constants.js | 4 ++ src/reducers/modals.js | 3 ++ src/styles/global.js | 18 +++++++- src/styles/theme.js | 2 + yarn.lock | 43 +++++++++--------- 15 files changed, 194 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index 8438abce..f27c85f6 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "bs58check": "^2.1.1", "color": "^3.0.0", "cross-env": "^5.1.3", - "downshift": "^1.26.0", + "downshift": "^1.26.1", "electron-store": "^1.3.0", "electron-updater": "^2.20.1", "fuse.js": "^3.2.0", @@ -80,7 +80,7 @@ "redux-thunk": "^2.2.0", "shortid": "^2.2.8", "source-map-support": "^0.5.3", - "styled-components": "^3.1.1", + "styled-components": "^3.1.2", "styled-system": "^1.1.1" }, "devDependencies": { @@ -113,7 +113,7 @@ "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.6.1", "flow-bin": "^0.64.0", - "flow-typed": "^2.2.3", + "flow-typed": "^2.3.0", "husky": "^0.14.3", "lint-staged": "^6.1.0", "node-loader": "^0.6.0", diff --git a/src/components/AccountPage.js b/src/components/AccountPage.js index 5de58ea0..94b6dd80 100644 --- a/src/components/AccountPage.js +++ b/src/components/AccountPage.js @@ -1,23 +1,32 @@ // @flow import React, { PureComponent, Fragment } from 'react' +import { compose } from 'redux' import { connect } from 'react-redux' +import { translate } from 'react-i18next' + +import { MODAL_SEND, MODAL_RECEIVE } from 'constants' import type { MapStateToProps } from 'react-redux' -import type { Account, AccountData } from 'types/common' +import type { T, Account, AccountData } from 'types/common' import { formatBTC } from 'helpers/format' import { getAccountById, getAccountData } from 'reducers/accounts' +import { openModal } from 'reducers/modals' -import TransactionsList from 'components/TransactionsList' import Box, { Card } from 'components/base/Box' -import Text from 'components/base/Text' +import Button from 'components/base/Button' +import Icon from 'components/base/Icon' import ReceiveBox from 'components/ReceiveBox' +import Text from 'components/base/Text' +import TransactionsList from 'components/TransactionsList' type Props = { + t: T, account: Account, accountData: AccountData, + openModal: Function, } const mapStateToProps: MapStateToProps<*, *, *> = (state, props) => ({ @@ -25,14 +34,45 @@ const mapStateToProps: MapStateToProps<*, *, *> = (state, props) => ({ accountData: getAccountData(state, props.match.params.id), }) +const mapDispatchToProps = { + openModal, +} + class AccountPage extends PureComponent { render() { - const { account, accountData } = this.props + const { account, accountData, openModal, t } = this.props return ( - - {`${account.name} account`} + + + {`${account.name} account`} + + + + + + + + + +