Skip to content

Commit

Permalink
release (#276)
Browse files Browse the repository at this point in the history
* Fabo/fix gas (#250)

* fix gas estimate

* linted

* fixed test

* do not keep data sources (#251)

* track failing transactions in Sentry (#249)

* correctly set the tx schema for a failing tx (#248)

* Fabo/remove per block caching as not working (#247)

* remove per block caching as not working

* fix memoized results

Co-authored-by: Ana G. <[email protected]>

* delete perblockcachedatasource (#253)

* Ana/fix balances in actionmodal (#255)

* fix action modal available balance

* include regen

* use dictionary for denomlookup

* use correct events for received txs (#257)

* enable account creation for some networks (#252)

* network update time metric added (#256)

* network update time metric added

* added missing dep

Co-authored-by: Fabian <[email protected]>

* Fix proposal deposit (#261)

* Remove denom handling from getDeposit()

* Revert undesired change

* delete package-lock.json

* localtestnet config change (#265)

* Ana/handle "address not from this network" error (#263)

* add check address function for all queries

* apply suggestions

* Ana/add fiatvalue to balances query (e-Money) (#262)

* preparation

* more preparation

* add fiatvalue field to balances query

* fix get account info

* apply suggestions

* apply one last suggestion

* suggestions+

Co-authored-by: Fabian <[email protected]>

* Ana/emoney fix expected returns with inflation and totalbacked (#243)

* fix expected returns with inflation and supply

* minor fixes. dictionary

* query exchange rates from emoney api

* fix infinite expected returns

* convert api url to const

* add eur value to totalbackedvalue. totalngm gains

* add important comment

* finish calculation

* lint

* catch errors with sentry

Co-authored-by: Fabian <[email protected]>

* readd coin conversion (#268)

* delete amount field (#274)

* Fabo/increase gas again (#271)

* icrease gas again

* fixed test

* Fabo/load all txs (even if more then first page in response) (#270)

* load all txs (even if more then first page in response)

* improved handling of txs

* missing renaming

* fixed paginated load

* add pagination fix also to cosmosV0-source

Co-authored-by: iambeone <[email protected]>
Co-authored-by: Ana G. <[email protected]>

* fixing issue with multiple senders in one event (#273)

* fixing issue with multiple senders in one event

* Update lib/source/cosmosV2-source.js

Co-authored-by: Fabian <[email protected]>

Co-authored-by: Ana G. <[email protected]>
Co-authored-by: iambeone <[email protected]>
Co-authored-by: Mario Pino <[email protected]>
  • Loading branch information
4 people authored Jan 18, 2020
1 parent 4321a85 commit be29a21
Show file tree
Hide file tree
Showing 15 changed files with 715 additions and 87 deletions.
2 changes: 1 addition & 1 deletion data/networks-local.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = [
rpc_url: config.testnetRPC,
api_url: config.testnetAPI,
bech32_prefix: 'cosmos',
source_class_name: 'source/cosmosV0-source',
source_class_name: 'source/cosmosV2-source',
block_listener_class_name: 'block-listeners/cosmos-node-subscription',
testnet: true,
feature_explore: true,
Expand Down
8 changes: 4 additions & 4 deletions data/networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"source_class_name": "source/regenV0-source",
"block_listener_class_name": "block-listeners/cosmos-node-subscription",
"testnet": true,
"feature_session": false,
"feature_session": true,
"feature_explore": true,
"feature_portfolio": true,
"feature_validators": true,
Expand Down Expand Up @@ -96,7 +96,7 @@
"source_class_name": "source/terraV3-source",
"block_listener_class_name": "block-listeners/cosmos-node-subscription",
"testnet": true,
"feature_session": false,
"feature_session": true,
"feature_explore": true,
"feature_portfolio": true,
"feature_validators": true,
Expand Down Expand Up @@ -125,8 +125,8 @@
"source_class_name": "source/emoneyV0-source",
"block_listener_class_name": "block-listeners/cosmos-node-subscription",
"testnet": true,
"feature_session": false,
"feature_explore": false,
"feature_session": true,
"feature_explore": true,
"feature_portfolio": false,
"feature_validators": true,
"feature_proposals": false,
Expand Down
14 changes: 12 additions & 2 deletions lib/block-listeners/cosmos-node-subscription.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const _ = require('lodash')
const io = require('@pm2/io')
const Tendermint = require('../rpc/tendermint')
const {
publishBlockAdded,
Expand All @@ -16,17 +17,26 @@ class CosmosNodeSubscription {
this.network = network
this.cosmosAPI = new CosmosApiClass(network)
this.store = store
this.lastupdate = 0
this.metric = io.metric({
name: `${this.network.id}_update`
})

// Create a RPC subscription for each network that will react to new block events.
Tendermint()
.connect(this.network.rpc_url)
.then(connectedClient => {
connectedClient.subscribe({ query: "tm.event='NewBlock'" }, event =>
connectedClient.subscribe({ query: "tm.event='NewBlock'" }, event => {
if (this.lastupdate) {
const diff = Date.now() - this.lastupdate
this.metric.set(diff)
}
this.lastupdate = Date.now()
setTimeout(
() => this.newBlockHandler(event.block.header.height),
WAIT_FOR_BLOCK_DELAY
)
)
})
})
.catch(e => {
Sentry.withScope(function(scope) {
Expand Down
4 changes: 2 additions & 2 deletions lib/controller/transaction/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ async function estimate() {
// const message = getMessage(tx.messageType, tx.txProperties, context)

try {
// const gasEstimate = (await message.simulate({ memo: tx.memo })) * 4 // we quadrupled the gas to be safe. rn there are several txs failing on cosmoshub-3
// const gasEstimate = await message.simulate({ memo: tx.memo }) + 100000
// HACK: fixed to this value for now. too high gas can lead to transactions never being included. too low gas can lead to rejected txs and cost the user money.
const gasEstimate = 450000
const gasEstimate = 550000

return {
gasEstimate,
Expand Down
8 changes: 4 additions & 4 deletions lib/reducers/cosmosV0-reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ const expectedRewardsPerToken = (validator, commission, annualProvision) => {
return annualDelegatorRewardsPerToken.div(1000000)
}

// reduce deposits to one number and filter by required denom
function getDeposit(proposal, bondDenom) {
// reduce deposits to one number
function getDeposit(proposal) {
return atoms(
proposal.total_deposit.reduce(
(sum, cur) => sum.plus(cur.denom === bondDenom ? cur.amount : 0),
(sum, cur) => sum.plus(cur.amount),
BigNumber(0)
)
)
Expand Down Expand Up @@ -163,7 +163,7 @@ function proposalReducer(
statusBeginTime: proposalBeginTime(proposal),
statusEndTime: proposalEndTime(proposal),
tally: tallyReducer(proposal, tally, totalBondedTokens),
deposit: getDeposit(proposal, 'uatom'), // TODO use denom lookup
deposit: getDeposit(proposal),
proposer: proposer.proposer
}
}
Expand Down
121 changes: 109 additions & 12 deletions lib/reducers/emoneyV0-reducers.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,126 @@
const terraV3Reducers = require('./terraV3-reducers')
const BigNumber = require('bignumber.js')
const fetch = require('node-fetch')
const _ = require('lodash')
const EMoneyAPIUrl = `https://api.e-money.com/v1/`
const exchangeAPIURL = `https://api.exchangeratesapi.io/latest?`
const Sentry = require('@sentry/node')

function expectedRewardsPerToken(
async function totalBackedValueReducer(totalBackedValue) {
const exchangeRates = await fetchTokenExchangeRates()
const token = `e`.concat(totalBackedValue.denom.substring(2))
const ticker = totalBackedValue.denom.substring(2).toUpperCase()
// First we calculate the fiat net value of the token's total supply in it counterpart
// fiat currency
// TODO Not all the tokens have yet their rate value in the e-Money API. So the calculation
// is not yet 100% accurate
const fiatValue = exchangeRates[token]
? BigNumber(totalBackedValue.amount)
.div(100000000)
.times(exchangeRates[token][ticker])
.toNumber()
: null
// Now that we have its net fiat value, we transform this value into euro
const { rates } = await fetchFiatExchangeRates(`EUR`, ticker)
const eurRate = ticker === `EUR` ? 1 : rates[ticker]
return (totalBackedValue = {
...totalBackedValue,
amount: exchangeRates[token]
? BigNumber(totalBackedValue.amount).times(
Object.values(exchangeRates[token])[0]
)
: BigNumber(totalBackedValue.amount),
// The total net EUR value of the token's total supply equals its net value in its
// counterpart fiat currency times this fiat currency's EUR rate
eurValue: fiatValue * eurRate
})
}

async function fetchTokenExchangeRates() {
return await fetch(`${EMoneyAPIUrl}rates.json`)
.then(r => r.json())
.catch(err => {
Sentry.withScope(function(scope) {
scope.setExtra('fetch', `${EMoneyAPIUrl}rates.json`)
Sentry.captureException(err)
})
})
}

async function fetchFiatExchangeRates(selectedFiatCurrency, ticker) {
return await fetch(
`${exchangeAPIURL}base=${selectedFiatCurrency}&symbols=${ticker}`
)
.then(r => r.json())
.catch(err => {
Sentry.withScope(function(scope) {
scope.setExtra(
'fetch',
`${exchangeAPIURL}base=${selectedFiatCurrency}&symbols=${ticker}`
)
Sentry.captureException(err)
})
})
}

async function expectedRewardsPerToken(
validator,
commission,
inflation,
totalBackedValue
inflations,
totalBackedValues
) {
const percentTotalStakedNGM = BigNumber(validator.votingPower).times(1000)
const totalNGMStakedToValidator = validator.tokens
const division = BigNumber(percentTotalStakedNGM)
.times(BigNumber(1).minus(commission))
.times(BigNumber(1).minus(BigNumber(commission)))
.div(BigNumber(totalNGMStakedToValidator))
// Now we need to multiply each total supply of backed tokens with its corresponding
// inflation
let accumulator = BigNumber(0)
const totalBackedValueDictionary = _.keyBy(totalBackedValues, 'denom')

inflations.forEach(inflation => {
accumulator = BigNumber(accumulator)
.plus(accumulator)
.plus(
BigNumber(inflation.inflation)
.times(totalBackedValueDictionary[inflation.denom].amount)
.div(1000000)
)
})
const totalBackedValuesTimesInflations = accumulator
// First we calculate the total value of rewards we get for staking one single
// NGM in this particular validator
const delegatorSharePerToken = BigNumber(inflation * totalBackedValue).div(
division
)
return delegatorSharePerToken.div(1000000)
// TODO
// Now we convert delegatorRewardsPerToken to the amount of NGM we can buy now
// with this reward
let delegatorSharePerToken = totalBackedValuesTimesInflations.div(division)
// In testnet some validators have commission at 100% and therefore division is
// equal to 0. Dividing by 0 we get infinity, and we want to make sure that
// we don't display such value
const infinity = new BigNumber(Infinity)
// This is just how BigNumber works. Comparing to 0 and if true, bignumber equals the given parameter.
// Documentation on this method can be found here: https://mikemcl.github.io/bignumber.js/#cmp
delegatorSharePerToken =
delegatorSharePerToken.comparedTo(infinity) === 0
? BigNumber(0)
: delegatorSharePerToken.div(1000000)
// Now we get the total net value in EUR of all token's total supplies
let eurAccumulator = 0
totalBackedValues.forEach(totalBackedValue => {
eurAccumulator += totalBackedValue.eurValue
})
const totalEURGains = eurAccumulator * delegatorSharePerToken.toNumber()
// How many NGM tokens can we buy with the total gain in EUR we make in a year's time?
// 0.50€ is the price the NGM tokens will be first sold. Therefore, this is the official value
// until they reach an exchange
const pricePerNGM = 0.5
const ngmGains = totalEURGains / pricePerNGM
// We divide by 1 because we assume 1 NGM > gain per 1 NGM
const expectedReturns = parseFloat(ngmGains / 1).toFixed(2)
// TODO the FE is the one converting to percentage now, so we need to divide by 100
return expectedReturns / 100
}

module.exports = {
...terraV3Reducers,
expectedRewardsPerToken
expectedRewardsPerToken,
totalBackedValueReducer
}
19 changes: 15 additions & 4 deletions lib/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,24 @@ const resolvers = {
},
maintenance: (_, __, { dataSources }) =>
dataSources.LunieDBAPI.getMaintenance(),
balances: async (_, { networkId, address }, { dataSources }) =>
remoteFetch(dataSources, networkId).getBalancesFromAddress(address),
balance: async (_, { networkId, address, denom }, { dataSources }) => {
balances: async (
_,
{ networkId, address, fiatCurrency },
{ dataSources }
) =>
remoteFetch(dataSources, networkId).getBalancesFromAddress(
address,
fiatCurrency
),
balance: async (
_,
{ networkId, address, denom, fiatCurrency },
{ dataSources }
) => {
const balances = await remoteFetch(
dataSources,
networkId
).getBalancesFromAddress(address)
).getBalancesFromAddress(address, fiatCurrency)
const balance = balances.find(balance => balance.denom === denom)
return balance || { denom, amount: 0 }
},
Expand Down
20 changes: 17 additions & 3 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ const typeDefs = gql`
amount: String
}
type Balance {
denom: String!
amount: String!
fiatValue: String
}
type Proposal {
networkId: String!
id: Int
Expand Down Expand Up @@ -139,7 +145,6 @@ const typeDefs = gql`
fee: Coin
signature: String!
value: String!
amount: String
undelegationEndTime: String
}
Expand Down Expand Up @@ -203,8 +208,17 @@ const typeDefs = gql`
networks: [Network]
network(id: String): Network
maintenance: [Maintenance]
balances(networkId: String!, address: String!): [Coin]
balance(networkId: String!, address: String!, denom: String!): Coin
balances(
networkId: String!
address: String!
fiatCurrency: String
): [Balance]
balance(
networkId: String!
address: String!
denom: String!
fiatCurrency: String
): Balance
overview(networkId: String!, address: String!): Overview
delegation(
networkId: String!
Expand Down
Loading

0 comments on commit be29a21

Please sign in to comment.