Skip to content

Commit 47f663b

Browse files
committed
added NAV pulses for payments (basically a diff of NAV decrease on scopes) and total NAV
1 parent 0eefa8d commit 47f663b

File tree

3 files changed

+102
-9
lines changed

3 files changed

+102
-9
lines changed

service/src/main/kotlin/io/provenance/explorer/domain/entities/NavEvents.kt

+50
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.jetbrains.exposed.sql.insertIgnore
1111
import org.jetbrains.exposed.sql.javatime.JavaLocalDateTimeColumnType
1212
import org.jetbrains.exposed.sql.javatime.datetime
1313
import org.jetbrains.exposed.sql.transactions.transaction
14+
import java.math.BigDecimal
1415
import java.sql.ResultSet
1516
import java.time.LocalDateTime
1617

@@ -180,6 +181,55 @@ class NavEventsRecord(id: EntityID<Int>) : IntEntity(id) {
180181
)
181182
}
182183
}
184+
185+
fun navPricesBetweenDays(
186+
startDateTime: LocalDateTime,
187+
endDateTime: LocalDateTime
188+
) = transaction {
189+
val query = """
190+
select c.denom,c.source, c.scope_id,
191+
c.price_amount as current_amount,
192+
c.volume as current_volume,
193+
max(c.block_time) as current_block_time,
194+
p.price_amount as previous_amount,
195+
p.volume as previous_volume,
196+
p.block_time as previous_block_time
197+
from nav_events c,
198+
(select p.scope_id, p.price_amount, p.volume, max(p.block_time) as block_time
199+
from nav_events p
200+
where p.source = 'metadata'
201+
and date_trunc('DAYS', block_time) = ?
202+
group by p.scope_id, p.price_amount, p.volume) as p
203+
where c.source = 'metadata'
204+
and date_trunc('DAYS', c.block_time) = ?
205+
and c.scope_id = p.scope_id
206+
group by c.denom, c.source, c.scope_id, c.price_amount, c.volume, p.price_amount, p.volume, p.block_time
207+
""".trimIndent()
208+
209+
val args = mutableListOf<Pair<ColumnType, *>>(
210+
Pair(JavaLocalDateTimeColumnType(), startDateTime),
211+
Pair(JavaLocalDateTimeColumnType(), endDateTime)
212+
)
213+
query.execAndMap(args) {
214+
val map = mutableMapOf<String, Any?>()
215+
(1..it.metaData.columnCount).forEach { index ->
216+
map[it.metaData.getColumnName(index)] = it.getObject(index)
217+
}
218+
map // return a list of map of column name/value
219+
}
220+
}
221+
222+
fun totalMetadataNavs() = transaction {
223+
val query = """
224+
select sum(price_amount)
225+
from (select scope_id, price_amount, row_number() over (partition by scope_id order by block_height desc) as r
226+
from nav_events where source = 'metadata' and price_amount > 0) s
227+
where r = 1
228+
""".trimIndent()
229+
query.execAndMap {
230+
BigDecimal(it.getString(1))
231+
}.firstOrNull() ?: BigDecimal.ZERO
232+
}
183233
}
184234

185235
var blockHeight by NavEventsTable.blockHeight

service/src/main/kotlin/io/provenance/explorer/domain/models/explorer/pulse/Enums.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ enum class PulseCacheType {
1818
PULSE_MARKET_CAP_METRIC,
1919
PULSE_TRANSACTION_VOLUME_METRIC,
2020
PULSE_FEES_AUCTIONS_METRIC,
21-
PULSE_RECEIVABLES_METRIC,
21+
PULSE_TODAYS_NAV_METRIC,
22+
PULSE_NAV_DECREASE_METRIC,
23+
PULSE_TOTAL_NAV_METRIC,
2224
PULSE_TRADE_SETTLEMENT_METRIC,
2325
PULSE_TRADE_VALUE_SETTLED_METRIC,
2426
PULSE_PARTICIPANTS_METRIC,

service/src/main/kotlin/io/provenance/explorer/service/PulseMetricService.kt

+49-8
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PulseMetricService(
4848
private val validatorService: ValidatorService,
4949
private val pricingService: PricingService,
5050
private val assetService: AssetService,
51-
private val exchangeGrpcClient: ExchangeGrpcClient
51+
private val exchangeGrpcClient: ExchangeGrpcClient,
5252
) {
5353
protected val logger = logger(PulseMetricService::class)
5454

@@ -69,6 +69,11 @@ class PulseMetricService(
6969
maximumSize(100)
7070
}.build()
7171

72+
/* so it turns out that the `usd` in metadata nav events
73+
use 3 decimal places - :|
74+
*/
75+
private val scopeNAVDecimal = inversePowerOfTen(3)
76+
7277
val base = UTILITY_TOKEN
7378
val quote = USD_UPPER
7479

@@ -264,9 +269,9 @@ class PulseMetricService(
264269
* Uses metadata module reported values to calculate receivables since
265270
* all data in metadata today is loan receivables
266271
*/
267-
private fun pulseReceivableValue(): PulseMetric =
272+
private fun pulseTodaysNavs(): PulseMetric =
268273
fetchOrBuildCacheFromDataSource(
269-
type = PulseCacheType.PULSE_RECEIVABLES_METRIC
274+
type = PulseCacheType.PULSE_TODAYS_NAV_METRIC
270275
) { // TODO technically correct assuming only metadata nav events are receivables
271276
NavEventsRecord.getNavEvents(
272277
fromDate = LocalDateTime.now().startOfDay(),
@@ -278,16 +283,48 @@ class PulseMetricService(
278283
it.scopeId
279284
}
280285
.sumOf { it.priceAmount!! }.toBigDecimal().let {
281-
/* so it turns out that the `usd` in metadata nav events
282-
use 3 decimal places - :|
283-
*/
284286
PulseMetric.build(
285287
base = USD_UPPER,
286-
amount = it.times(inversePowerOfTen(3))
288+
amount = it.times(scopeNAVDecimal)
289+
)
290+
}
291+
}
292+
293+
private fun dailyNavDecrease(): PulseMetric =
294+
fetchOrBuildCacheFromDataSource(
295+
type = PulseCacheType.PULSE_NAV_DECREASE_METRIC
296+
) {
297+
val today = LocalDateTime.now().startOfDay()
298+
NavEventsRecord.navPricesBetweenDays(
299+
startDateTime = today.minusDays(1),
300+
endDateTime = today
301+
).map {
302+
val currentAmount = BigDecimal(it["current_amount"].toString())
303+
val previousAmount = BigDecimal(it["previous_amount"].toString())
304+
val changeAmount = previousAmount.minus(currentAmount)
305+
306+
Triple(currentAmount, previousAmount, changeAmount)
307+
}.filter { it.third >= BigDecimal.ZERO }
308+
.sumOf { it.third }.let {
309+
PulseMetric.build(
310+
base = USD_UPPER,
311+
amount = it.times(scopeNAVDecimal)
287312
)
288313
}
289314
}
290315

316+
private fun totalMetadataNavs(): PulseMetric =
317+
fetchOrBuildCacheFromDataSource(
318+
type = PulseCacheType.PULSE_TOTAL_NAV_METRIC
319+
) {
320+
NavEventsRecord.totalMetadataNavs().let {
321+
PulseMetric.build(
322+
base = USD_UPPER,
323+
amount = it.times(scopeNAVDecimal)
324+
)
325+
}
326+
}
327+
291328
/**
292329
* Retrieves the transaction volume for the last 30 days to build
293330
* metric chart data
@@ -510,7 +547,11 @@ class PulseMetricService(
510547
PulseCacheType.HASH_SUPPLY_METRIC -> hashMetric(type)
511548
PulseCacheType.PULSE_MARKET_CAP_METRIC -> pulseMarketCap()
512549
PulseCacheType.PULSE_TRANSACTION_VOLUME_METRIC -> transactionVolume()
513-
PulseCacheType.PULSE_RECEIVABLES_METRIC -> pulseReceivableValue()
550+
551+
PulseCacheType.PULSE_TODAYS_NAV_METRIC -> pulseTodaysNavs()
552+
PulseCacheType.PULSE_NAV_DECREASE_METRIC -> dailyNavDecrease()
553+
PulseCacheType.PULSE_TOTAL_NAV_METRIC -> totalMetadataNavs()
554+
514555
PulseCacheType.PULSE_TRADE_SETTLEMENT_METRIC -> pulseTradesSettled()
515556
PulseCacheType.PULSE_TRADE_VALUE_SETTLED_METRIC -> pulseTradeValueSettled()
516557
PulseCacheType.PULSE_PARTICIPANTS_METRIC -> totalParticipants()

0 commit comments

Comments
 (0)