output btc & eth calculations

This commit is contained in:
Matthias Kretschmann 2019-05-06 14:02:49 +02:00
parent 6ae353d5da
commit 79e1ad5042
Signed by: m
GPG Key ID: 606EEEF3C479A91F
11 changed files with 84 additions and 42 deletions

View File

@ -5,12 +5,21 @@
---
- [Features](#features)
- [Usage](#usage)
- [Build packages](#build-packages)
- [Data Sources](#data-sources)
---
## Features
- show Ocean Token balances from a list of Ethereum account addresses
- show a total balance of all account balances
- convert those balances against multiple currencies
- re-fetches everything automatically every minute
- balances are fetched via etherscan.io API
- spot prices are fetched from coingecko.com API
## Usage
Clone, add adresses, and run:
@ -42,8 +51,3 @@ On a Mac and Linux machine, packaging requires [`wine`](https://www.winehq.org)
```bash
brew install wine
```
## Data Sources
- balances are checked via etherscan.io API
- spot prices are fetched from coingecko.com API

View File

@ -115,12 +115,25 @@ button {
padding-right: 2%;
}
.label {
color: #8b98a9;
font-size: .85rem;
display: block;
white-space: nowrap;
margin-top: .3rem;
transition: color .2s ease-out;
}
.number-unit:hover .label {
color: #f6388a;
}
.number {
margin: 0;
transition: .15s ease-out;
font-weight: 400;
-webkit-app-region: no-drag;
-webkit-user-select: auto;
-webkit-user-select: text;
font-size: 1rem;
display: inline-block;
padding: 0 .3rem;
@ -132,14 +145,6 @@ button {
animation: updated .5s ease-out forwards;
}
.label {
color: #8b98a9;
font-size: .85rem;
display: block;
white-space: nowrap;
margin-top: .3rem;
}
.number-unit-wrap--accounts {
min-height: 55px;
}
@ -149,6 +154,10 @@ button {
border-bottom: 1px solid #e2e2e2;
}
.number-unit--main:hover .label {
color: #8b98a9;
}
.dark .number-unit--main {
border-bottom-color: #303030;
}

View File

@ -21,7 +21,6 @@ export default class App extends PureComponent {
<Titlebar />
<div className="app__content">
<main className="main">
<Actions />
<Total />
<div className="number-unit-wrap number-unit-wrap--accounts">
@ -33,6 +32,8 @@ export default class App extends PureComponent {
}
</Consumer>
</div>
<Actions />
</main>
</div>
</AppProvider>

View File

@ -1,5 +1,6 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { openUrl } from '../util/openUrl'
import Balance from './Balance'
export default class Account extends PureComponent {
@ -19,12 +20,16 @@ export default class Account extends PureComponent {
const { balance, address } = account
return (
<div className="number-unit">
<a
onClick={() =>
openUrl(`https://etherscan.io/address/${address}#tokentxns`)
}
title="Click to view on Etherscan"
className="number-unit"
>
<Balance balance={balance} />
<span className="label" title={address}>
{address.substring(0, 12)}...
</span>
</div>
<span className="label">{address.substring(0, 12)}...</span>
</a>
)
}
}

View File

@ -7,11 +7,17 @@ export default class Actions extends PureComponent {
return (
<div className="actions">
<Consumer>
{({ toggleCurrencies }) => (
{({ toggleCurrencies, accounts }) => (
<>
<button onClick={() => toggleCurrencies('ocean')}>OCEAN</button>
<button onClick={() => toggleCurrencies('eur')}>EUR</button>
<button onClick={() => toggleCurrencies('usd')}>USD</button>
{accounts.length > 0 &&
Object.keys(accounts[0].balance).map(currency => (
<button
key={currency}
onClick={() => toggleCurrencies(currency)}
>
{currency}
</button>
))}
</>
)}
</Consumer>

View File

@ -4,16 +4,18 @@ import { Consumer } from '../store/createContext'
import { numberFormatter, fiatFormatter } from '../util/moneyFormatter'
const Balance = ({ balance }) => {
const { ocean, eur, usd } = balance
const { ocean, btc, eth, eur, usd } = balance
return (
<h1 className="number">
<Consumer>
{({ currency }) =>
currency === 'ocean' ? (
<span className="balance" title={numberFormatter(ocean)}>
Ọ {numberFormatter(ocean) || 0}
</span>
<span className="balance">Ọ {numberFormatter(ocean) || 0}</span>
) : currency === 'btc' ? (
<span className="balance"> {numberFormatter(btc) || 0}</span>
) : currency === 'eth' ? (
<span className="balance">Ξ {numberFormatter(eth) || 0}</span>
) : currency === 'eur' ? (
<span className="balance">{fiatFormatter('EUR', eur)}</span>
) : (
@ -28,6 +30,8 @@ const Balance = ({ balance }) => {
Balance.propTypes = {
balance: PropTypes.shape({
ocean: PropTypes.number.isRequired,
btc: PropTypes.number.isRequired,
eth: PropTypes.number.isRequired,
eur: PropTypes.number.isRequired,
usd: PropTypes.number.isRequired
})

View File

@ -23,11 +23,15 @@ const Total = () => (
<Consumer>
{({ accounts }) => {
const totalOcean = calculateTotalBalance(accounts, 'ocean')
const totalBtc = calculateTotalBalance(accounts, 'btc')
const totalEth = calculateTotalBalance(accounts, 'eth')
const totalEur = calculateTotalBalance(accounts, 'eur')
const totalUsd = calculateTotalBalance(accounts, 'usd')
const balance = {
ocean: totalOcean,
btc: totalBtc,
eth: totalEth,
eur: totalEur,
usd: totalUsd
}

View File

@ -18,7 +18,7 @@ const height = 380
const isDarkMode = systemPreferences.isDarkMode()
const createWindow = () => {
const createWindow = async () => {
mainWindow = new BrowserWindow({
width: width,
height: height,
@ -47,13 +47,12 @@ const createWindow = () => {
REACT_DEVELOPER_TOOLS
} = require('electron-devtools-installer')
installExtension(REACT_DEVELOPER_TOOLS)
.then(name => {
console.log(`Added Extension: ${name}`) // eslint-disable-line no-console
})
.catch(err => {
console.log('An error occurred: ', err) // eslint-disable-line no-console
})
try {
const name = await installExtension(REACT_DEVELOPER_TOOLS)
console.log(`Added Extension: ${name}`) // eslint-disable-line no-console
} catch (error) {
console.log('An error occurred: ', error) // eslint-disable-line no-console
}
}
mainWindow.once('ready-to-show', () => {

View File

@ -1,4 +1,5 @@
const { app, Menu } = require('electron')
const { openUrl } = require('./util/openUrl')
const template = [
{
@ -70,7 +71,7 @@ const template = [
{
label: 'Learn More',
click() {
require('electron').shell.openExternal('https://electron.atom.io')
openUrl('https://electron.atom.io')
}
}
]

View File

@ -56,11 +56,11 @@ export default class AppProvider extends PureComponent {
fetchPrice = async () => {
const json = await this.fetch(
'https://api.coingecko.com/api/v3/simple/price?ids=ocean-protocol&vs_currencies=usd,eur'
'https://api.coingecko.com/api/v3/simple/price?ids=ocean-protocol&vs_currencies=btc,eth,usd,eur'
)
const { usd, eur } = json['ocean-protocol']
return { usd, eur }
const { btc, eth, usd, eur } = json['ocean-protocol']
return { btc, eth, usd, eur }
}
setBalances = async () => {
@ -68,7 +68,7 @@ export default class AppProvider extends PureComponent {
// when they are changed instead of resetting all to 0 here
this.clearAccounts()
const { usd, eur } = await this.fetchPrice()
const { btc, eth, usd, eur } = await this.fetchPrice()
accounts.map(async account => {
const oceanBalance = await this.fetchBalance(account)
@ -77,6 +77,8 @@ export default class AppProvider extends PureComponent {
address: account,
balance: {
ocean: oceanBalance || 0,
btc: oceanBalance * btc || 0,
eth: oceanBalance * eth || 0,
eur: oceanBalance * eur || 0,
usd: oceanBalance * usd || 0
}

7
src/util/openUrl.js Normal file
View File

@ -0,0 +1,7 @@
const { shell } = require('electron')
const openUrl = url => {
shell.openExternal(url)
}
export { openUrl }