diff --git a/app/components/budget-balances/component.js b/app/components/budget-balances/component.js index 39b6aa0a..26d6264e 100644 --- a/app/components/budget-balances/component.js +++ b/app/components/budget-balances/component.js @@ -1,10 +1,13 @@ import Component from '@glimmer/component'; import { inject as service } from '@ember/service'; -import { alias } from '@ember/object/computed'; export default class BudgetBalancesComponent extends Component { @service communityFunds; - @alias('communityFunds.balances') balances; + + get balancesSorted () { + return this.communityFunds.balances + .sortBy('confirmed_balance').reverse(); + } get loading () { return !this.communityFunds.balancesLoaded; diff --git a/app/components/budget-balances/template.hbs b/app/components/budget-balances/template.hbs index 745ad630..2e4c228d 100644 --- a/app/components/budget-balances/template.hbs +++ b/app/components/budget-balances/template.hbs @@ -7,11 +7,19 @@ - {{#each this.balances as |balance|}} + {{#each this.balancesSorted as |balance|}} - {{balance.token.symbol}} - {{balance.confirmed_balance}} - ~{{balance.balanceUSD}} USD + + {{balance.token.description}} + + + {{fmt-number balance.confirmed_balance}} sats + + + ~{{balance.balanceUSD}} USD + {{/each}} diff --git a/app/helpers/fmt-number.js b/app/helpers/fmt-number.js new file mode 100644 index 00000000..7fecc813 --- /dev/null +++ b/app/helpers/fmt-number.js @@ -0,0 +1,6 @@ +import { helper } from '@ember/component/helper'; + +export default helper(function fmtNumber(number) { + const lang = navigator.language || navigator.userLanguage; + return number.toLocaleString(lang); +}); diff --git a/app/services/community-funds.js b/app/services/community-funds.js index e431149c..ff49fc38 100644 --- a/app/services/community-funds.js +++ b/app/services/community-funds.js @@ -1,7 +1,7 @@ -import Service, { inject as service } from '@ember/service'; -import { tracked } from '@glimmer/tracking'; import { A } from '@ember/array'; import { task } from 'ember-concurrency-decorators'; +import { tracked } from '@glimmer/tracking'; +import Service, { inject as service } from '@ember/service'; import config from 'kredits-web/config/environment'; export default class CommunityFundsService extends Service { @@ -12,9 +12,20 @@ export default class CommunityFundsService extends Service { @task *fetchBalances () { - yield fetch(config.btcBalanceAPI).then(res => res.json()) - .then(res => { - return this.processBalances(res); + const promises = []; + const balances = config.communityFundsAPI.balances; + + for (const item of Object.keys(balances)) { + const c = balances[item]; + promises.push( + this.fetchBalance(c.url) + .then(res => { return this.processBalance(res, c) }) + ) + } + + yield Promise.all(promises) + .then(() => { + this.balancesLoaded = true; }) .catch(err => { console.log(`[community-funds] Fetching balances failed:`); @@ -22,18 +33,21 @@ export default class CommunityFundsService extends Service { }); } - async processBalances (res) { + async fetchBalance(url) { + return fetch(url).then(res => res.json()); + } + + async processBalance (res, config) { await this.exchangeRates.fetchRates(); + // Format and round the approximate USD value const lang = navigator.language || navigator.userLanguage; - const balanceUSD = res.confirmed_balance * this.exchangeRates.btcusd; + const balanceUSD = (res.confirmed_balance / 100000000) * this.exchangeRates.btcusd; res.balanceUSD = Math.round(balanceUSD).toLocaleString(lang); this.balances.pushObject({ ...res, - ...{ token: { name: 'BTC', symbol: 'BTC'} } + ...{ token: { icon: `/img/${config.icon}`, symbol: config.symbol, description: config.description } } }); - - this.balancesLoaded = true; } } diff --git a/app/services/exchange-rates.js b/app/services/exchange-rates.js index f56547f5..03d6b7ae 100644 --- a/app/services/exchange-rates.js +++ b/app/services/exchange-rates.js @@ -19,7 +19,13 @@ export default class ExchangeRatesService extends Service { @tracked btceur = 0; @tracked btcusd = 0; + get exchangeRatesLoaded () { + return (this.btceur !== 0) && (this.btcusd !== 0); + } + async fetchRates (source='bitstamp') { + if (this.exchangeRatesLoaded) return; + switch(source) { case 'bitstamp': this.btceur = await fetchFromBitstamp('btceur'); diff --git a/app/styles/components/_budget-balances.scss b/app/styles/components/_budget-balances.scss index 3a8263df..1357e7a2 100644 --- a/app/styles/components/_budget-balances.scss +++ b/app/styles/components/_budget-balances.scss @@ -16,8 +16,12 @@ section#funds { } th, td { - font-size: 1.2rem; vertical-align: text-bottom; + + img { + max-height: 1.5rem; + max-width: 1.5rem; + } } th { @@ -35,8 +39,13 @@ section#funds { } &.fiat-amount { + font-size: 1.2rem; color: rgba(255,255,255,0.8); } + + span.unit { + font-size: 1.5rem; + } } } } diff --git a/config/environment.js b/config/environment.js index 15321bfa..8cc59592 100644 --- a/config/environment.js +++ b/config/environment.js @@ -45,7 +45,22 @@ module.exports = function(environment) { 'BTC': '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599' }, - btcBalanceAPI: 'https://api.kosmos.org/kredits/onchain_btc_balance', + communityFundsAPI: { + balances: { + onchain: { + icon: 'icon-btc.png', + symbol: 'BTC', + description: 'BTC on chain', + url: 'https://api.kosmos.org/btcpay/onchain_btc_balance' + }, + lightning: { + icon: 'icon-btc-lightning.png', + symbol: 'BTC', + description: 'BTC on Lightning Network', + url: 'https://api.kosmos.org/btcpay/lightning_btc_balance' + } + } + }, corsProxy: 'https://cors.5apps.com/?uri=' }; @@ -66,6 +81,9 @@ module.exports = function(environment) { protocol: 'http', gatewayUrl: 'http://localhost:8080/ipfs' }; + + ENV.communityFundsAPI.balances.onchain.url = 'http://localhost:3000/api/btcpay/onchain_btc_balance'; + ENV.communityFundsAPI.balances.lightning.url = 'http://localhost:3000/api/btcpay/lightning_btc_balance'; } if (environment === 'test') { diff --git a/public/img/icon-btc-lightning.png b/public/img/icon-btc-lightning.png new file mode 100644 index 00000000..1deb8c55 Binary files /dev/null and b/public/img/icon-btc-lightning.png differ diff --git a/public/img/icon-btc.png b/public/img/icon-btc.png new file mode 100644 index 00000000..70694134 Binary files /dev/null and b/public/img/icon-btc.png differ