Skip to content

Commit

Permalink
Adds support for BAT in brave payments
Browse files Browse the repository at this point in the history
Resolves brave#10945

Auditors:

Test Plan:
  • Loading branch information
NejcZdovc committed Sep 14, 2017
1 parent 5e2cfb3 commit 995a476
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 88 deletions.
16 changes: 8 additions & 8 deletions app/common/lib/ledgerExportUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ module.exports.getPublisherVoteData = (transactions, viewingIds) => {
* Generates a contribution breakdown by publisher in an array of CSV rows from an array of transactions
* @example
* txUtil.getTransactionCSVRows(client.state.transactions)
* // [ ['Publisher,Votes,Fraction,BTC,USD'],
* // [ ['Publisher,Votes,Fraction,BAT,USD'],
* // ['chronicle.com,2,0.04081632653061224,0.0000033221,0.20 USD'],
* // ['waitbutwhy.com,3,0.061224489795918366,0.0000049832,0.31 USD'],
* // ['archlinux.org,1,0.02040816326530612,0.0000016611,0.10 USD'],
Expand Down Expand Up @@ -234,13 +234,13 @@ module.exports.getTransactionCSVRows = (transactions, viewingIds, addTotalRow, s

const currency = (publishers.length ? txContribData[publishers[0]].contribution.currency : 'USD')

const headerRow = ['Publisher', 'Votes', 'Fraction', 'BTC', currency].join(',')
const headerRow = ['Publisher', 'Votes', 'Fraction', 'BAT', currency].join(',')

var totalsRow = {
label: 'TOTAL',
votes: 0,
fraction: 0,
btc: 0,
bat: 0,
fiat: 0
}

Expand All @@ -249,10 +249,10 @@ module.exports.getTransactionCSVRows = (transactions, viewingIds, addTotalRow, s
rows = rows.concat(publishers.map(function (pub) {
var pubRow = txContribData[pub]

let rowBTC = pubRow.contribution.satoshis / Math.pow(10, 10)
let rowBAT = pubRow.contribution.satoshis / Math.pow(10, 10)
totalsRow.votes += pubRow.votes
totalsRow.fraction += pubRow.fraction
totalsRow.btc += rowBTC
totalsRow.bat += rowBAT

if (pubRow.contribution.currency === currency) {
totalsRow.fiat += parseFloat(pubRow.contribution.fiat || '0')
Expand All @@ -264,7 +264,7 @@ module.exports.getTransactionCSVRows = (transactions, viewingIds, addTotalRow, s
pub,
pubRow.votes,
pubRow.fraction,
rowBTC,
rowBAT,
pubRow.contribution.fiat.toFixed(2) + ' ' + pubRow.contribution.currency
].join(',')
}))
Expand All @@ -275,7 +275,7 @@ module.exports.getTransactionCSVRows = (transactions, viewingIds, addTotalRow, s
totalsRow.label,
totalsRow.votes,
totalsRow.fraction,
totalsRow.btc,
totalsRow.bat,
totalsRow.fiat.toFixed(2) + ' ' + currency
].join(','))
}
Expand All @@ -287,7 +287,7 @@ module.exports.getTransactionCSVRows = (transactions, viewingIds, addTotalRow, s
* Generates a contribution breakdown by publisher in an array of CSV rows from an array of transactions
* @example
* txUtil.getTransactionCSVText(state.transactions)
* // 'Publisher,Votes,Fraction,BTC,USD\nchronicle.com,2,0.04081632653061224,0.0000033221,0.20 USD\nwaitbutwhy.com,3,0.061224489795918366,0.0000049832,0.31 USD\narchlinux.org,1,0.02040816326530612,0.0000016611,0.10 USD /.../'
* // 'Publisher,Votes,Fraction,BAT,USD\nchronicle.com,2,0.04081632653061224,0.0000033221,0.20 USD\nwaitbutwhy.com,3,0.061224489795918366,0.0000049832,0.31 USD\narchlinux.org,1,0.02040816326530612,0.0000016611,0.10 USD /.../'
*
* @param {Object[]} transactions - array of transactions
* @param {string[]=} viewingIds - OPTIONAL array/string with one or more viewingIds to filter transactions by (if empty, uses all tx)
Expand Down
19 changes: 11 additions & 8 deletions app/common/lib/ledgerUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,20 @@ module.exports.shouldTrackView = (view, responseList) => {
return false
}

module.exports.btcToCurrencyString = (btc, ledgerData) => {
const balance = Number(btc || 0)
module.exports.batToCurrencyString = (bat, ledgerData) => {
const balance = Number(bat || 0)
const currency = ledgerData.get('currency') || 'USD'

if (balance === 0) {
return `0 ${currency}`
}

if (ledgerData.get('btc') && typeof ledgerData.get('amount') === 'number') {
const btcValue = ledgerData.get('btc') / ledgerData.get('amount')
const fiatValue = (balance / btcValue).toFixed(2)
const ledgerBat = ledgerData.get('bat')
const amount = ledgerData.get('amount')

if (ledgerBat && typeof amount === 'number') {
const batValue = ledgerBat / amount
const fiatValue = (balance / batValue).toFixed(2)
let roundedValue = Math.floor(fiatValue)
const diff = fiatValue - roundedValue

Expand All @@ -66,7 +69,7 @@ module.exports.btcToCurrencyString = (btc, ledgerData) => {
return `${roundedValue.toFixed(2)} ${currency}`
}

return `${balance} BTC`
return `${balance} BAT`
}

module.exports.formattedTimeFromNow = (timestamp) => {
Expand All @@ -89,11 +92,11 @@ module.exports.walletStatus = (ledgerData) => {
const pendingFunds = Number(ledgerData.get('unconfirmed') || 0)

if (pendingFunds + Number(ledgerData.get('balance') || 0) <
0.9 * Number(ledgerData.get('btc') || 0)) {
0.9 * Number(ledgerData.get('bat') || 0)) {
status.id = 'insufficientFundsStatus'
} else if (pendingFunds > 0) {
status.id = 'pendingFundsStatus'
status.args = {funds: module.exports.btcToCurrencyString(pendingFunds, ledgerData)}
status.args = {funds: module.exports.batToCurrencyString(pendingFunds, ledgerData)}
} else if (transactions && transactions.size > 0) {
status.id = 'defaultWalletStatus'
} else {
Expand Down
88 changes: 31 additions & 57 deletions app/ledger.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ const {fileUrl} = require('../js/lib/appUrlUtil')
// "only-when-needed" loading...
let ledgerBalance = null
let ledgerClient = null
let ledgerGeoIP = null
let ledgerPublisher = null

// testing data
Expand Down Expand Up @@ -102,7 +101,8 @@ const clientOptions = {
rulesTestP: process.env.LEDGER_RULES_TESTING,
verboseP: process.env.LEDGER_VERBOSE,
server: process.env.LEDGER_SERVER_URL,
createWorker: app.createWorker
createWorker: app.createWorker,
version: 'v2'
}

var doneTimer
Expand Down Expand Up @@ -271,6 +271,7 @@ const doAction = (state, action) => {
break

case appConstants.APP_NAVIGATOR_HANDLER_REGISTERED:
// TODO will this be changed when switching to BAT
ledgerInfo.hasBitcoinHandler = (action.protocol === 'bitcoin')
appActions.updateLedgerInfo(underscore.omit(ledgerInfo, [ '_internal' ]))
break
Expand Down Expand Up @@ -708,7 +709,7 @@ var initialize = (paymentsEnabled) => {
}
if (client) return

if (!ledgerPublisher) ledgerPublisher = require('ledger-publisher')
if (!ledgerPublisher) ledgerPublisher = require('bat-publisher')
ruleset = []
ledgerPublisher.ruleset.forEach(rule => { if (rule.consequent) ruleset.push(rule) })
cacheRuleSet(ruleset)
Expand Down Expand Up @@ -781,7 +782,7 @@ var initialize = (paymentsEnabled) => {
}

var clientprep = () => {
if (!ledgerClient) ledgerClient = require('ledger-client')
if (!ledgerClient) ledgerClient = require('bat-client')
ledgerInfo._internal.debugP = ledgerClient.prototype.boolion(process.env.LEDGER_CLIENT_DEBUG)
publisherInfo._internal.debugP = ledgerClient.prototype.boolion(process.env.LEDGER_PUBLISHER_DEBUG)
publisherInfo._internal.verboseP = ledgerClient.prototype.boolion(process.env.LEDGER_PUBLISHER_VERBOSE)
Expand All @@ -795,13 +796,13 @@ var enable = (paymentsEnabled) => {
publisherInfo._internal.enabled = paymentsEnabled
if (synopsis) return updatePublisherInfo()

if (!ledgerPublisher) ledgerPublisher = require('ledger-publisher')
if (!ledgerPublisher) ledgerPublisher = require('bat-publisher')
synopsis = new (ledgerPublisher.Synopsis)()
fs.readFile(pathName(synopsisPath), (err, data) => {
var initSynopsis = () => {
var value

// cf., the `Synopsis` constructor, https://github.com/brave/ledger-publisher/blob/master/index.js#L167
// cf., the `Synopsis` constructor, https://github.com/brave/bat-publisher/blob/master/index.js#L167
value = getSetting(settings.PAYMENTS_MINIMUM_VISIT_TIME)
if (!value) {
value = 8 * 1000
Expand Down Expand Up @@ -1522,15 +1523,15 @@ var ledgerInfo = {
currency: undefined
},
rates: {
[currency]: undefined // bitcoin value in <currency>
[currency]: undefined // bat value in <currency>
},
satoshis: undefined,
probi: undefined,
fee: undefined
},
submissionStamp: undefined,
submissionId: undefined,
count: undefined,
satoshis: undefined,
probi: undefined,
votes: undefined,
ballots: {
[publisher]: undefined
Expand All @@ -1540,16 +1541,16 @@ var ledgerInfo = {
],

// set from ledger client's state.paymentInfo OR client's getWalletProperties
// Bitcoin wallet address
// BAT wallet address
address: undefined,

// Bitcoin wallet balance (truncated BTC and satoshis)
// BAT wallet balance (truncated BAT and probi)
balance: undefined,
unconfirmed: undefined,
satoshis: undefined,
probi: undefined,

// the desired contribution (the btc value approximates the amount/currency designation)
btc: undefined,
// the desired contribution (the bat value approximates the amount/currency designation)
bat: undefined,
amount: undefined,
currency: undefined,

Expand All @@ -1568,30 +1569,24 @@ var ledgerInfo = {

hasBitcoinHandler: false,

// geoIP/exchange information
countryCode: undefined,
exchangeInfo: undefined,

_internal: {
exchangeExpiry: 0,
exchanges: {},
geoipExpiry: 0
exchanges: {}
},
error: null
}

var updateLedgerInfo = () => {
var info = ledgerInfo._internal.paymentInfo
var now = underscore.now()

if (info) {
underscore.extend(ledgerInfo,
underscore.pick(info, [ 'address', 'passphrase', 'balance', 'unconfirmed', 'satoshis', 'btc', 'amount',
underscore.pick(info, [ 'address', 'passphrase', 'balance', 'unconfirmed', 'probi', 'bat', 'amount',
'currency' ]))
if ((!info.buyURLExpires) || (info.buyURLExpires > now)) {
ledgerInfo.buyURL = info.buyURL
ledgerInfo.buyMaximumUSD = 6
}
ledgerInfo.buyURL = info.buyURL
ledgerInfo.buyMaximumUSD = 6 // TODO what happens with this one

// TODO do we still need this check?
if (typeof process.env.ADDFUNDS_URL !== 'undefined') {
ledgerInfo.buyURLFrame = true
ledgerInfo.buyURL = process.env.ADDFUNDS_URL + '?' +
Expand All @@ -1604,29 +1599,6 @@ var updateLedgerInfo = () => {
underscore.extend(ledgerInfo, ledgerInfo._internal.cache || {})
}

if ((client) && (now > ledgerInfo._internal.geoipExpiry)) {
ledgerInfo._internal.geoipExpiry = now + (5 * msecs.minute)

if (!ledgerGeoIP) ledgerGeoIP = require('ledger-geoip')
return ledgerGeoIP.getGeoIP(client.options, (err, provider, result) => {
if (err) console.warn('ledger geoip warning: ' + JSON.stringify(err, null, 2))
if (result) ledgerInfo.countryCode = result

ledgerInfo.exchangeInfo = ledgerInfo._internal.exchanges[ledgerInfo.countryCode]

if (now <= ledgerInfo._internal.exchangeExpiry) return updateLedgerInfo()

ledgerInfo._internal.exchangeExpiry = now + msecs.day
roundtrip({ path: '/v1/exchange/providers' }, client.options, (err, response, body) => {
if (err) console.error('ledger exchange error: ' + JSON.stringify(err, null, 2))

ledgerInfo._internal.exchanges = body || {}
ledgerInfo.exchangeInfo = ledgerInfo._internal.exchanges[ledgerInfo.countryCode]
updateLedgerInfo()
})
})
}

if (ledgerInfo._internal.debugP) {
console.log('\nupdateLedgerInfo: ' + JSON.stringify(underscore.omit(ledgerInfo, [ '_internal' ]), null, 2))
}
Expand Down Expand Up @@ -1896,7 +1868,8 @@ var getStateInfo = (state) => {
if (!state.properties.wallet) return

ledgerInfo.paymentId = state.properties.wallet.paymentId
ledgerInfo.passphrase = state.properties.wallet.keychains.passphrase
if (!ledgerClient) ledgerClient = require('bat-client')
ledgerInfo.passphrase = ledgerClient.prototype.getWalletPassphrase(state)

ledgerInfo.created = !!state.properties.wallet
ledgerInfo.creating = !ledgerInfo.created
Expand Down Expand Up @@ -1936,7 +1909,7 @@ var getStateInfo = (state) => {
}

// Observe ledger client state.transactions for changes.
// Called by getStateInfo(). Updated state provided by ledger-client.
// Called by getStateInfo(). Updated state provided by bat-client.
var cachedTransactions = null
var observeTransactions = (transactions) => {
if (underscore.isEqual(cachedTransactions, transactions)) {
Expand All @@ -1961,7 +1934,7 @@ var getBalance = () => {
balanceTimeoutId = setTimeout(getBalance, 1 * msecs.minute)
if (!ledgerInfo.address) return

if (!ledgerBalance) ledgerBalance = require('ledger-balance')
if (!ledgerBalance) ledgerBalance = require('bat-balance')
ledgerBalance.getBalance(ledgerInfo.address, underscore.extend({ balancesP: true }, client.options),
(err, provider, result) => {
var unconfirmed
Expand Down Expand Up @@ -2021,12 +1994,12 @@ var getPaymentInfo = () => {
return
}

info = underscore.extend(info, underscore.pick(body, [ 'buyURL', 'buyURLExpires', 'balance', 'unconfirmed', 'satoshis' ]))
info = underscore.extend(info, underscore.pick(body, [ 'buyURL', 'balance', 'unconfirmed', 'probi' ]))
info.address = client.getWalletAddress()
if ((amount) && (currency)) {
info = underscore.extend(info, { amount: amount, currency: currency })
if ((body.rates) && (body.rates[currency])) {
info.btc = (amount / body.rates[currency]).toFixed(8)
info.bat = (amount / body.rates[currency]).toFixed(8) // TODO maybe use probi here for exact bat amount
}
}
ledgerInfo._internal.paymentInfo = info
Expand Down Expand Up @@ -2070,7 +2043,8 @@ var cacheReturnValue = () => {
if (!ledgerInfo._internal.cache) ledgerInfo._internal.cache = {}
cache = ledgerInfo._internal.cache

paymentURL = 'bitcoin:' + info.address + '?amount=' + info.btc + '&label=' + encodeURI('Brave Software')
// TODO do we need to change this?
paymentURL = 'bitcoin:' + info.address + '?amount=' + info.bat + '&label=' + encodeURI('Brave Software')
if (cache.paymentURL === paymentURL) return

cache.paymentURL = paymentURL
Expand Down Expand Up @@ -2187,8 +2161,8 @@ const showEnabledNotifications = () => {
const sufficientBalanceToReconcile = () => {
const balance = Number(ledgerInfo.balance || 0)
const unconfirmed = Number(ledgerInfo.unconfirmed || 0)
return ledgerInfo.btc &&
(balance + unconfirmed > 0.9 * Number(ledgerInfo.btc))
return ledgerInfo.bat &&
(balance + unconfirmed > 0.9 * Number(ledgerInfo.bat))
}

const shouldShowNotificationAddFunds = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const getSetting = require('../../../../../js/settings').getSetting
const settings = require('../../../../../js/constants/settings')
const aboutActions = require('../../../../../js/about/aboutActions')

// TODO refactor me to BAT
class BitcoinDashboard extends ImmutableComponent {
constructor () {
super()
Expand Down
4 changes: 2 additions & 2 deletions app/renderer/components/preferences/payment/enabledContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {StyleSheet, css} = require('aphrodite/no-important')
const moment = require('moment')

// util
const {btcToCurrencyString, formattedDateFromTimestamp, walletStatus} = require('../../../../common/lib/ledgerUtil')
const {batToCurrencyString, formattedDateFromTimestamp, walletStatus} = require('../../../../common/lib/ledgerUtil')
const {l10nErrorText} = require('../../../../common/lib/httpUtil')
const {changeSetting} = require('../../../lib/settingsUtil')

Expand Down Expand Up @@ -82,7 +82,7 @@ class EnabledContent extends ImmutableComponent {
}

return <section className={css(styles.balance)}>
<FormTextbox data-test-id='fundsAmount' readOnly value={btcToCurrencyString(value, ledgerData)} />
<FormTextbox data-test-id='fundsAmount' readOnly value={batToCurrencyString(value, ledgerData)} />
<a className={cx({
[globalStyles.appIcons.question]: true,
[css(styles.balance__iconLink)]: true
Expand Down
4 changes: 2 additions & 2 deletions app/renderer/components/preferences/payment/ledgerRecovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const React = require('react')
const {StyleSheet, css} = require('aphrodite/no-important')

// util
const {btcToCurrencyString} = require('../../../../common/lib/ledgerUtil')
const {batToCurrencyString} = require('../../../../common/lib/ledgerUtil')

// components
const ImmutableComponent = require('../../immutableComponent')
Expand Down Expand Up @@ -43,7 +43,7 @@ class LedgerRecoveryContent extends ImmutableComponent {

render () {
const l10nDataArgs = {
balance: btcToCurrencyString(this.props.ledgerData.get('balance'), this.props.ledgerData)
balance: batToCurrencyString(this.props.ledgerData.get('balance'), this.props.ledgerData)
}
const recoverySucceeded = this.props.ledgerData.get('recoverySucceeded')
const recoveryError = this.props.ledgerData.getIn(['error', 'error'])
Expand Down
1 change: 1 addition & 0 deletions app/renderer/components/preferences/paymentsTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class PaymentsTab extends ImmutableComponent {
}

get overlayTitle () {
// TODO are we still limited by coinbase?
if (coinbaseCountries.indexOf(this.props.ledgerData.get('countryCode')) > -1) {
return 'addFunds'
} else {
Expand Down
Loading

0 comments on commit 995a476

Please sign in to comment.