@@ -9,13 +9,21 @@ import { config } from './config'
99import { REDIS_COINRANK_KEY_PREFIX } from './constants'
1010import { asReturnGetRate , getExchangeRates } from './rates'
1111import {
12+ asCoinrankAssetReq ,
1213 asCoinrankReq ,
1314 asExchangeRateResponse ,
15+ CoinrankAssetReq ,
1416 CoinrankRedis ,
1517 CoinrankReq
1618} from './types'
1719import { asExtendedReq } from './utils/asExtendedReq'
18- import { DbDoc , getAsync , hmgetAsync , setAsync } from './utils/dbUtils'
20+ import {
21+ DbDoc ,
22+ getAsync ,
23+ hgetallAsync ,
24+ hmgetAsync ,
25+ setAsync
26+ } from './utils/dbUtils'
1927import {
2028 addIso ,
2129 fromCode ,
@@ -314,15 +322,127 @@ const sendExchangeRates: express.RequestHandler = (req, res, next): void => {
314322 res . json ( { data : exReq . requestedRatesResult . data } )
315323}
316324
317- const sendCoinranks : express . RequestHandler = async (
325+ const getRedisMarkets = async (
326+ fiatCode : string
327+ ) : Promise < CoinrankRedis | undefined > => {
328+ const { ratesServerAddress } = config
329+ const now = new Date ( )
330+ const nowTimestamp = now . getTime ( )
331+
332+ const jsonString = await getAsync ( `${ REDIS_COINRANK_KEY_PREFIX } _${ fiatCode } ` )
333+ let redisResult : CoinrankRedis = JSON . parse ( jsonString )
334+
335+ if ( fiatCode !== defaultFiatCode ) {
336+ const lastUpdated =
337+ redisResult != null ? new Date ( redisResult . lastUpdate ) . getTime ( ) : 0
338+
339+ // If no result in redis or it's out of date
340+ if ( redisResult == null || nowTimestamp - lastUpdated > EXPIRE_TIME ) {
341+ // Attempt to scale prices by foreign exchange rate
342+
343+ // Get exchange rate
344+ const result = await fetch (
345+ `${ ratesServerAddress } /v2/exchangeRate?currency_pair=${ defaultFiatCode } _${ fiatCode } `
346+ )
347+ const resultJson = await result . json ( )
348+ const { exchangeRate } = asExchangeRateResponse ( resultJson )
349+ const rate = Number ( exchangeRate )
350+
351+ // Get USD rankings
352+ const jsonString = await getAsync (
353+ `${ REDIS_COINRANK_KEY_PREFIX } _${ defaultFiatCode } `
354+ )
355+ redisResult = JSON . parse ( jsonString )
356+ let { markets } = redisResult
357+
358+ // Modify fiat-related fields with the forex rate
359+ markets = markets . map ( m => ( {
360+ ...m ,
361+ marketCap : m . marketCap * rate ,
362+ price : m . price * rate ,
363+ volume24h : m . volume24h * rate ,
364+ high24h : m . high24h * rate ,
365+ low24h : m . low24h * rate ,
366+ priceChange24h : m . priceChange24h * rate ,
367+ marketCapChange24h : m . marketCapChange24h * rate ,
368+ circulatingSupply : m . circulatingSupply * rate ,
369+ totalSupply : m . totalSupply * rate ,
370+ maxSupply : m . maxSupply * rate ,
371+ allTimeHigh : m . allTimeHigh * rate ,
372+ allTimeLow : m . allTimeLow * rate
373+ } ) )
374+
375+ // Update redis cache
376+ const redisData : CoinrankRedis = {
377+ markets,
378+ lastUpdate : now . toISOString ( )
379+ }
380+ await setAsync (
381+ `${ REDIS_COINRANK_KEY_PREFIX } _${ fiatCode } ` ,
382+ JSON . stringify ( redisData )
383+ )
384+ }
385+ }
386+
387+ return redisResult
388+ }
389+
390+ const sendCoinrankList : express . RequestHandler = async (
318391 req ,
319392 res ,
320393 next
321394) : Promise < void > => {
322- const { ratesServerAddress } = config
323- const now = new Date ( )
324- const nowTimestamp = now . getTime ( )
395+ const data = await hgetallAsync ( 'coingecko' )
396+ res . json ( { data } )
397+ }
325398
399+ const sendCoinrankAsset : express . RequestHandler = async (
400+ req ,
401+ res ,
402+ next
403+ ) : Promise < void > => {
404+ const exReq = req as ExpressRequest
405+ if ( exReq == null ) return next ( 500 )
406+
407+ let query : CoinrankAssetReq
408+ try {
409+ query = asCoinrankAssetReq ( req . query )
410+ } catch ( e ) {
411+ res
412+ . status ( 400 )
413+ . send ( `Error: ${ e instanceof Error ? e . message : 'Unknown error' } ` )
414+ return
415+ }
416+ const { fiatCode } = query
417+ const { assetId } = req . params
418+
419+ try {
420+ const redisResult = await getRedisMarkets ( fiatCode )
421+
422+ if ( redisResult == null ) {
423+ res . status ( 400 ) . send ( `Unable to get results for fiatCode ${ fiatCode } ` )
424+ return
425+ }
426+
427+ const { markets } = redisResult
428+ const market = markets . find ( m => m . assetId === assetId )
429+ if ( market == null ) {
430+ res . status ( 404 ) . send ( `assetId ${ assetId } not found` )
431+ return
432+ }
433+
434+ res . json ( { data : market } )
435+ } catch ( e ) {
436+ const err : any = e
437+ res . status ( 500 ) . send ( err . message )
438+ }
439+ }
440+
441+ const sendCoinranks : express . RequestHandler = async (
442+ req ,
443+ res ,
444+ next
445+ ) : Promise < void > => {
326446 const exReq = req as ExpressRequest
327447 if ( exReq == null ) return next ( 500 )
328448
@@ -350,67 +470,8 @@ const sendCoinranks: express.RequestHandler = async (
350470 . send ( `Invalid length param: ${ length } . Must be between 1-100` )
351471 return
352472 }
353- const jsonString = await getAsync (
354- `${ REDIS_COINRANK_KEY_PREFIX } _${ fiatCode } `
355- )
473+ const redisResult = await getRedisMarkets ( fiatCode )
356474
357- let redisResult : CoinrankRedis = JSON . parse ( jsonString )
358-
359- if ( fiatCode !== defaultFiatCode ) {
360- const lastUpdated =
361- redisResult != null ? new Date ( redisResult . lastUpdate ) . getTime ( ) : 0
362-
363- // If no result in redis or it's out of date
364- if ( redisResult == null || nowTimestamp - lastUpdated > EXPIRE_TIME ) {
365- // Attempt to scale prices by foreign exchange rate
366-
367- // Get exchange rate
368- const result = await fetch (
369- `${ ratesServerAddress } /v2/exchangeRate?currency_pair=${ defaultFiatCode } _${ fiatCode } `
370- )
371- const resultJson = await result . json ( )
372- const { exchangeRate } = asExchangeRateResponse ( resultJson )
373- const rate = Number ( exchangeRate )
374-
375- // Get USD rankings
376- const jsonString = await getAsync (
377- `${ REDIS_COINRANK_KEY_PREFIX } _${ defaultFiatCode } `
378- )
379- redisResult = JSON . parse ( jsonString )
380- let { markets } = redisResult
381-
382- // Modify fiat-related fields with the forex rate
383- markets = markets . map ( m => ( {
384- ...m ,
385- marketCap : m . marketCap * rate ,
386- price : m . price * rate ,
387- volume24h : m . volume24h * rate ,
388- high24h : m . high24h * rate ,
389- low24h : m . low24h * rate ,
390- priceChange24h : m . priceChange24h * rate ,
391- marketCapChange24h : m . marketCapChange24h * rate ,
392- circulatingSupply : m . circulatingSupply * rate ,
393- totalSupply : m . totalSupply * rate ,
394- maxSupply : m . maxSupply * rate ,
395- allTimeHigh : m . allTimeHigh * rate ,
396- allTimeLow : m . allTimeLow * rate
397- } ) )
398- const data = markets . slice ( start - 1 , start + length )
399-
400- res . json ( { data } )
401-
402- // Update redis cache
403- const redisData : CoinrankRedis = {
404- markets,
405- lastUpdate : now . toISOString ( )
406- }
407- await setAsync (
408- `${ REDIS_COINRANK_KEY_PREFIX } _${ fiatCode } ` ,
409- JSON . stringify ( redisData )
410- )
411- return
412- }
413- }
414475 if ( redisResult == null ) {
415476 res . status ( 400 ) . send ( `Unable to get results for fiatCode ${ fiatCode } ` )
416477 return
@@ -472,6 +533,8 @@ export const exchangeRateRouterV2 = (): express.Router => {
472533 ] )
473534
474535 router . get ( '/coinrank' , [ sendCoinranks ] )
536+ router . get ( '/coinrankAsset/:assetId' , [ sendCoinrankAsset ] )
537+ router . get ( '/coinrankList' , [ sendCoinrankList ] )
475538
476539 return router
477540}
0 commit comments