const _ = require('lodash/fp') const NodeCache = require('node-cache') const base = require('../geth/base') const T = require('../../../time') const { BALANCE_FETCH_SPEED_MULTIPLIER } = require('../../../constants') const NAME = 'infura' function run (account) { if (!account.endpoint) throw new Error('Need to configure API endpoint for Infura') const endpoint = _.startsWith('https://')(account.endpoint) ? account.endpoint : `https://${account.endpoint}` base.connect(endpoint) } const txsCache = new NodeCache({ stdTTL: T.hour / 1000, checkperiod: T.minute / 1000, deleteOnExpire: true }) function shouldGetStatus (tx) { const timePassedSinceTx = Date.now() - new Date(tx.created) const timePassedSinceReq = Date.now() - new Date(txsCache.get(tx.id).lastReqTime) if (timePassedSinceTx < 3 * T.minutes) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 10 * T.seconds if (timePassedSinceTx < 5 * T.minutes) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 20 * T.seconds if (timePassedSinceTx < 30 * T.minutes) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > T.minute if (timePassedSinceTx < 1 * T.hour) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 2 * T.minute if (timePassedSinceTx < 3 * T.hours) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 5 * T.minute if (timePassedSinceTx < 1 * T.day) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > T.hour return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > T.hour } // Override geth's getStatus function to allow for different polling timing function getStatus (account, tx, requested, settings, operatorId) { if (_.isNil(txsCache.get(tx.id))) { txsCache.set(tx.id, { lastReqTime: Date.now() }) } // return last available response if (!shouldGetStatus(tx)) { return Promise.resolve(txsCache.get(tx.id).res) } return base.getStatus(account, tx, requested, settings, operatorId) .then(res => { if (res.status === 'confirmed') { txsCache.del(tx.id) // Transaction reached final status, can trim it from the caching obj } else { txsCache.set(tx.id, { lastReqTime: Date.now(), res }) txsCache.ttl(tx.id, T.hour / 1000) } return res }) } module.exports = _.merge(base, { NAME, run, getStatus, fetchSpeed: BALANCE_FETCH_SPEED_MULTIPLIER.SLOW })