Skip to content

Commit

Permalink
Merge pull request #632 from curvefi/refactor/prices-api-llama-ohlc
Browse files Browse the repository at this point in the history
refactor: use prices api for llamma ohlc
  • Loading branch information
0xAlunara authored Jan 30, 2025
2 parents 9f5b5f3 + 1fcd182 commit 324e821
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 145 deletions.
13 changes: 13 additions & 0 deletions apps/main/src/global-extensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { UTCTimestamp } from 'lightweight-charts'

declare global {
interface Date {
getUTCTimestamp(): UTCTimestamp
}
}

Date.prototype.getUTCTimestamp = function () {
return (this.getTime() / 1000) as UTCTimestamp
}

export {}
156 changes: 83 additions & 73 deletions apps/main/src/lend/store/createOhlcChartSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {
TimeOptions,
FetchingStatus,
LpPriceOhlcDataFormatted,
LlammaOhlcApiResponse,
VolumeData,
LlamaBaselinePriceData,
OraclePriceData,
Expand All @@ -14,14 +13,17 @@ import type {
LlammaTradeEvent,
LlammaControllerEvent,
} from 'ui/src/Chart/types'
import type { UTCTimestamp } from 'lightweight-charts'
import type { Address, Chain } from '@curvefi/prices-api'
import { getOracle } from '@curvefi/prices-api/lending'
import { getOHLC } from '@curvefi/prices-api/llamma'

import produce from 'immer'

import networks from '@/lend/networks'
import { convertToLocaleTimestamp } from '@ui/Chart/utils'
import { ChainId } from '@/lend/types/lend.types'

type OHLCTimeUnit = Parameters<typeof getOHLC>[0]['units']

type SliceState = {
chartLlammaOhlc: {
data: LpPriceOhlcDataFormatted[]
Expand Down Expand Up @@ -215,17 +217,17 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
const network = networks[chainId].id.toLowerCase()

try {
const lendOhlcFetch = await fetch(
`https://prices.curve.fi/v1/lending/llamma_ohlc/${network}/${poolAddress}?agg_number=${interval}&agg_units=${timeUnit}&start=${start}&end=${end}`,
)
const lendOhlcResponse = await lendOhlcFetch.json()

// detail appears when no curve oracle pools can be found in the api
if (lendOhlcResponse.detail) {
throw new Error(lendOhlcResponse.detail)
}
const ohlc = await getOHLC({
endpoint: 'lending',
chain: network as Chain,
llamma: poolAddress as Address,
interval,
units: timeUnit as OHLCTimeUnit,
start,
end,
})

if (lendOhlcResponse.data.length === 0) {
if (ohlc.length === 0) {
throw new Error('No LLAMMA OHLC data found. Data may be unavailable for this pool.')
}

Expand All @@ -234,25 +236,25 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
let oraclePriceArray: OraclePriceData[] = []
let ohlcDataArray: LpPriceOhlcDataFormatted[] = []

for (const item of lendOhlcResponse.data) {
for (const item of ohlc) {
volumeArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
value: item.volume,
color: item.open < item.close ? '#26a69982' : '#ef53507e',
})

baselinePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
base_price: item.base_price,
time: item.time.getUTCTimestamp(),
base_price: item.basePrice,
})

oraclePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
value: item.oracle_price,
time: item.time.getUTCTimestamp(),
value: item.oraclePrice,
})

ohlcDataArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
open: item.open,
close: item.close,
high: item.high,
Expand All @@ -272,7 +274,7 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
produce((state: State) => {
state[sliceKey].chartLlammaOhlc.data = ohlcDataArray
state[sliceKey].chartLlammaOhlc.refetchingCapped = ohlcDataArray.length < 298
state[sliceKey].chartLlammaOhlc.lastFetchEndTime = lendOhlcResponse.data[0].time
state[sliceKey].chartLlammaOhlc.lastFetchEndTime = ohlc[0].time.getUTCTimestamp()
state[sliceKey].chartLlammaOhlc.fetchStatus = 'READY'
state[sliceKey].chartLlammaOhlc.volumeData = volumeArray
state[sliceKey].chartLlammaOhlc.oraclePriceData = oraclePriceArray
Expand Down Expand Up @@ -308,35 +310,40 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
const network = networks[chainId].id.toLowerCase()

try {
const llammaOhlcFetch = await fetch(
`https://prices.curve.fi/v1/lending/llamma_ohlc/${network}/${poolAddress}?agg_number=${interval}&agg_units=${timeUnit}&start=${start}&end=${end}`,
)
const llammaOhlcResponse: LlammaOhlcApiResponse = await llammaOhlcFetch.json()
const ohlc = await getOHLC({
endpoint: 'lending',
chain: network as Chain,
llamma: poolAddress as Address,
interval,
units: timeUnit as OHLCTimeUnit,
start,
end,
})

let volumeArray: VolumeData[] = []
let baselinePriceArray: LlamaBaselinePriceData[] = []
let oraclePriceArray: OraclePriceData[] = []
let ohlcDataArray: LpPriceOhlcDataFormatted[] = []

for (const item of llammaOhlcResponse.data) {
for (const item of ohlc) {
volumeArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
value: item.volume,
color: item.open < item.close ? '#26a69982' : '#ef53507e',
})

baselinePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
base_price: item.base_price,
time: item.time.getUTCTimestamp(),
base_price: item.basePrice,
})

oraclePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
value: item.oracle_price,
time: item.time.getUTCTimestamp(),
value: item.oraclePrice,
})

ohlcDataArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
open: item.open,
close: item.close,
high: item.high,
Expand All @@ -350,7 +357,7 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
oracleData: oraclePriceArray,
baselineData: baselinePriceArray,
refetchingCapped: ohlcDataArray.length < 299,
lastFetchEndTime: llammaOhlcResponse.data[0].time,
lastFetchEndTime: ohlc[0].time.getUTCTimestamp(),
}
} catch (error) {
set(
Expand Down Expand Up @@ -397,41 +404,40 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
const checkSummedController = getAddress(controller)

try {
const oracleOhlcDataFetch = await fetch(
`https://prices.curve.fi/v1/lending/oracle_ohlc/${network}/${checkSummedController}?agg_number=${interval}&agg_units=${timeUnit}&start=${start}&end=${end}`,
)
const oracleOhlcResponse = await oracleOhlcDataFetch.json()

// detail appears when no curve oracle pools can be found in the api
if (oracleOhlcResponse.detail) {
throw new Error(oracleOhlcResponse.detail)
}
const { pools, ohlc } = await getOracle({
chain: network as Chain,
controller: checkSummedController as Address,
interval,
units: timeUnit as OHLCTimeUnit,
start,
end,
})

if (oracleOhlcResponse.data?.length === 0) {
if (ohlc.length === 0) {
throw new Error('No oracle OHLC data found. Data may be unavailable for this pool.')
}

let baselinePriceArray: LlamaBaselinePriceData[] = []
let oraclePriceArray: OraclePriceData[] = []
let ohlcDataArray: LpPriceOhlcDataFormatted[] = []

for (const item of oracleOhlcResponse.data) {
if (item.base_price) {
for (const item of ohlc) {
if (item.basePrice) {
baselinePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
base_price: item.base_price,
time: item.time.getUTCTimestamp(),
base_price: item.basePrice,
})
}

if (item.oracle_price) {
if (item.oraclePrice) {
oraclePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
value: item.oracle_price,
time: item.time.getUTCTimestamp(),
value: item.oraclePrice,
})
}

ohlcDataArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
open: item.open,
close: item.close,
high: item.high,
Expand All @@ -443,17 +449,17 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
produce((state: State) => {
state[sliceKey].chartOraclePoolOhlc.data = ohlcDataArray
state[sliceKey].chartOraclePoolOhlc.collateralToken = {
address: oracleOhlcResponse.oracle_pools[0].collateral_address,
symbol: oracleOhlcResponse.oracle_pools[0].collateral_symbol,
address: pools[0].collateralAddress,
symbol: pools[0].collateralSymbol,
}
state[sliceKey].chartOraclePoolOhlc.borrowedToken = {
address: oracleOhlcResponse.oracle_pools[oracleOhlcResponse.oracle_pools.length - 1].borrowed_address,
symbol: oracleOhlcResponse.oracle_pools[oracleOhlcResponse.oracle_pools.length - 1].borrowed_symbol,
address: pools[pools.length - 1].borrowedAddress,
symbol: pools[pools.length - 1].borrowedSymbol,
}
state[sliceKey].chartOraclePoolOhlc.oraclePriceData = oraclePriceArray
state[sliceKey].chartOraclePoolOhlc.baselinePriceData = baselinePriceArray
state[sliceKey].chartOraclePoolOhlc.refetchingCapped = ohlcDataArray.length < 299
state[sliceKey].chartOraclePoolOhlc.lastFetchEndTime = oracleOhlcResponse.data[0].time
state[sliceKey].chartOraclePoolOhlc.lastFetchEndTime = ohlc[0].time.getUTCTimestamp()
state[sliceKey].chartOraclePoolOhlc.fetchStatus = 'READY'
}),
)
Expand Down Expand Up @@ -488,32 +494,36 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
const checkSummedController = getAddress(controller)

try {
const oracleOhlcDataFetch = await fetch(
`https://prices.curve.fi/v1/lending/oracle_ohlc/${network}/${checkSummedController}?agg_number=${interval}&agg_units=${timeUnit}&start=${start}&end=${end}`,
)
const oracleOhlcResponse = await oracleOhlcDataFetch.json()
const { pools, ohlc } = await getOracle({
chain: network as Chain,
controller: checkSummedController as Address,
interval,
units: timeUnit as OHLCTimeUnit,
start,
end,
})

let baselinePriceArray: LlamaBaselinePriceData[] = []
let oraclePriceArray: OraclePriceData[] = []
let ohlcDataArray: LpPriceOhlcDataFormatted[] = []

for (const item of oracleOhlcResponse.data) {
if (item.base_price) {
for (const item of ohlc) {
if (item.basePrice) {
baselinePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
base_price: item.base_price,
time: item.time.getUTCTimestamp(),
base_price: item.basePrice,
})
}

if (item.oracle_price) {
if (item.oraclePrice) {
oraclePriceArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
value: item.oracle_price,
time: item.time.getUTCTimestamp(),
value: item.oraclePrice,
})
}

ohlcDataArray.push({
time: convertToLocaleTimestamp(item.time) as UTCTimestamp,
time: item.time.getUTCTimestamp(),
open: item.open,
close: item.close,
high: item.high,
Expand All @@ -526,14 +536,14 @@ const createOhlcChart = (set: SetState<State>, get: GetState<State>) => ({
oracleData: oraclePriceArray,
baselineData: baselinePriceArray,
refetchingCapped: ohlcDataArray.length < 299,
lastFetchEndTime: oracleOhlcResponse.data[0].time,
lastFetchEndTime: ohlc[0].time.getUTCTimestamp(),
collateralToken: {
address: oracleOhlcResponse.oracle_pools[0].collateral_address,
symbol: oracleOhlcResponse.oracle_pools[0].collateral_symbol,
address: pools[0].collateralAddress,
symbol: pools[0].collateralSymbol,
},
borrowedToken: {
address: oracleOhlcResponse.oracle_pools[oracleOhlcResponse.oracle_pools.length - 1].borrowed_address,
symbol: oracleOhlcResponse.oracle_pools[oracleOhlcResponse.oracle_pools.length - 1].borrowed_symbol,
address: pools[pools.length - 1].borrowedAddress,
symbol: pools[pools.length - 1].borrowedSymbol,
},
}
} catch (error) {
Expand Down
Loading

0 comments on commit 324e821

Please sign in to comment.