Skip to content

Commit d17f403

Browse files
committed
Add coinrank v2 endpoint
1 parent 9f270ed commit d17f403

File tree

5 files changed

+93
-9
lines changed

5 files changed

+93
-9
lines changed

src/coinrankEngine.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@ const NUM_PAGES = 8
1717

1818
const { defaultFiatCode } = config
1919

20-
export const coinrankEngine = async (): Promise<void> => {
20+
export const coinrankEngine = async (
21+
runOnce: boolean = false
22+
): Promise<void> => {
2123
while (true) {
2224
try {
2325
const { coinrankOffsetSeconds, coinrankIntervalSeconds } = config
24-
const delay = getDelay({
25-
now: new Date(),
26-
intervalSeconds: coinrankIntervalSeconds,
27-
offsetSeconds: coinrankOffsetSeconds
28-
})
26+
const delay = runOnce
27+
? 0
28+
: getDelay({
29+
now: new Date(),
30+
intervalSeconds: coinrankIntervalSeconds,
31+
offsetSeconds: coinrankOffsetSeconds
32+
})
2933

3034
logger(`**** COINRANK ENGINE SNOOZING ${delay / 1000}s`)
3135
await snooze(delay)
@@ -76,5 +80,6 @@ export const coinrankEngine = async (): Promise<void> => {
7680
})
7781
logger(message)
7882
}
83+
if (runOnce) break
7984
}
8085
}

src/exchangeRateRouter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ const sendExchangeRates: express.RequestHandler = (req, res, next): void => {
351351
res.json({ data: exReq.requestedRatesResult.data })
352352
}
353353

354-
const getRedisMarkets = async (
354+
export const getRedisMarkets = async (
355355
fiatCode: string
356356
): Promise<CoinrankRedis | undefined> => {
357357
const { ratesServerAddress } = config

src/v3/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { pickMethod, pickPath } from 'serverlet'
44
import { makeExpressRoute } from 'serverlet/express'
55

66
import { config } from '../config'
7-
import { ratesV2, rateV2 } from './legacyRouter'
7+
import { ratesV2, rateV2, sendCoinranksV2 } from './legacyRouter'
88
import { heartbeatV3, ratesV3 } from './router'
99

1010
async function main(): Promise<void> {
@@ -16,6 +16,7 @@ function server(): void {
1616
'/': pickMethod({ GET: heartbeatV3 }),
1717
'/v2/exchangeRate': pickMethod({ GET: rateV2 }),
1818
'/v2/exchangeRates': pickMethod({ POST: ratesV2 }),
19+
'/v2/coinrank': pickMethod({ GET: sendCoinranksV2 }),
1920
'/v3/rates': pickMethod({ POST: ratesV3 })
2021
})
2122

src/v3/legacyRouter.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type { HttpResponse } from 'serverlet'
22
import type { ExpressRequest } from 'serverlet/express'
33

4-
import { asExchangeRatesReq } from '../exchangeRateRouter'
4+
import { asExchangeRatesReq, getRedisMarkets } from '../exchangeRateRouter'
5+
import { asCoinrankReq, type CoinrankReq } from '../types'
56
import { ratesV3, v2CurrencyCodeMapSyncDoc } from './router'
67
import { asGetRatesParams } from './types'
78
import { convertV2, convertV3ToV2 } from './v2converter'
@@ -70,3 +71,73 @@ export const rateV2 = async (
7071
}
7172
}
7273
}
74+
75+
export const sendCoinranksV2 = async (
76+
request: ExpressRequest
77+
): Promise<HttpResponse> => {
78+
if (request.req.query == null) {
79+
return {
80+
status: 400,
81+
headers: { 'content-type': 'application/json' },
82+
body: JSON.stringify({ error: 'Invalid request query' })
83+
}
84+
}
85+
let query: CoinrankReq
86+
try {
87+
query = asCoinrankReq(request.req.query)
88+
} catch (e) {
89+
return {
90+
status: 400,
91+
headers: { 'content-type': 'application/json' },
92+
body: JSON.stringify({ error: `Invalid request query ${String(e)}` })
93+
}
94+
}
95+
const { fiatCode, start, length } = query
96+
97+
try {
98+
if (start < 1 || start > 2000) {
99+
return {
100+
status: 400,
101+
headers: { 'content-type': 'application/json' },
102+
body: JSON.stringify({
103+
error: `Invalid start param: ${start}. Must be between 1-2000`
104+
})
105+
}
106+
}
107+
if (length < 1 || length > 100) {
108+
return {
109+
status: 400,
110+
headers: { 'content-type': 'application/json' },
111+
body: JSON.stringify({
112+
error: `Invalid length param: ${length}. Must be between 1-100`
113+
})
114+
}
115+
}
116+
const redisResult = await getRedisMarkets(fiatCode)
117+
118+
if (redisResult == null) {
119+
return {
120+
status: 400,
121+
headers: { 'content-type': 'application/json' },
122+
body: JSON.stringify({
123+
error: `Unable to get results for fiatCode ${fiatCode}`
124+
})
125+
}
126+
}
127+
128+
const { markets } = redisResult
129+
const data = markets.slice(start - 1, start + length)
130+
131+
return {
132+
status: 200,
133+
headers: { 'content-type': 'application/json' },
134+
body: JSON.stringify({ data })
135+
}
136+
} catch (e: unknown) {
137+
return {
138+
status: 500,
139+
headers: { 'content-type': 'application/json' },
140+
body: JSON.stringify({ error: `Internal server error ${String(e)}` })
141+
}
142+
}
143+
}

src/v3/providers/coingecko/coingecko.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { asArray, asMaybe, asNumber, asObject, asString } from 'cleaners'
22
import { asCouchDoc, syncedDocument } from 'edge-server-tools'
33

4+
import { coinrankEngine } from '../../../coinrankEngine'
45
import { config } from '../../../config'
56
import { dateOnly, snooze } from '../../../utils/utils'
67
import { TOKEN_TYPES_KEY } from '../../constants'
@@ -355,6 +356,12 @@ export const coingecko: RateProvider = {
355356
{
356357
frequency: 'day',
357358
engine: tokenMapping
359+
},
360+
{
361+
frequency: 120,
362+
engine: async () => {
363+
await coinrankEngine(true)
364+
}
358365
}
359366
]
360367
}

0 commit comments

Comments
 (0)