diff --git a/src/abacus-ts/calculators/blockRewards.ts b/src/abacus-ts/calculators/blockRewards.ts new file mode 100644 index 000000000..ff08b36ab --- /dev/null +++ b/src/abacus-ts/calculators/blockRewards.ts @@ -0,0 +1,21 @@ +import { IndexerHistoricalBlockTradingReward } from '@/types/indexer/indexerApiGen'; +import { keyBy, maxBy } from 'lodash'; + +import { MustBigNumber } from '@/lib/numbers'; + +import { Loadable } from '../lib/loadable'; +import { mapLoadableData } from '../lib/mapLoadable'; +import { mergeObjects } from '../lib/mergeObjects'; + +function calculateBlockRewards( + liveTransfers: Loadable, + restTransfers: Loadable +) { + const getRewardsById = (data: Loadable) => + mapLoadableData(data, (d) => keyBy(d, (reward) => reward.createdAtHeight)); + return mergeObjects( + getRewardsById(liveTransfers).data ?? {}, + getRewardsById(restTransfers).data ?? {}, + (first, second) => maxBy([first, second], (f) => MustBigNumber(f.createdAtHeight).toNumber())! + ); +} diff --git a/src/abacus-ts/calculators/fills.ts b/src/abacus-ts/calculators/fills.ts new file mode 100644 index 000000000..ae2fb76ca --- /dev/null +++ b/src/abacus-ts/calculators/fills.ts @@ -0,0 +1,21 @@ +import { IndexerCompositeFillObject } from '@/types/indexer/indexerManual'; +import { keyBy, maxBy } from 'lodash'; + +import { MustBigNumber } from '@/lib/numbers'; + +import { Loadable } from '../lib/loadable'; +import { mapLoadableData } from '../lib/mapLoadable'; +import { mergeObjects } from '../lib/mergeObjects'; + +function calculateFills( + liveFills: Loadable, + restFills: Loadable +) { + const getFillsById = (data: Loadable) => + mapLoadableData(data, (d) => keyBy(d, (fill) => fill.id ?? '')); + return mergeObjects( + getFillsById(liveFills).data ?? {}, + getFillsById(restFills).data ?? {}, + (first, second) => maxBy([first, second], (f) => MustBigNumber(f.createdAtHeight).toNumber())! + ); +} diff --git a/src/abacus-ts/calculators/transfers.ts b/src/abacus-ts/calculators/transfers.ts new file mode 100644 index 000000000..af4b86b7c --- /dev/null +++ b/src/abacus-ts/calculators/transfers.ts @@ -0,0 +1,21 @@ +import { IndexerTransferResponseObject } from '@/types/indexer/indexerApiGen'; +import { keyBy, maxBy } from 'lodash'; + +import { MustBigNumber } from '@/lib/numbers'; + +import { Loadable } from '../lib/loadable'; +import { mapLoadableData } from '../lib/mapLoadable'; +import { mergeObjects } from '../lib/mergeObjects'; + +function calculateTransfers( + liveTransfers: Loadable, + restTransfers: Loadable +) { + const getTransfersById = (data: Loadable) => + mapLoadableData(data, (d) => keyBy(d, (transfer) => transfer.id)); + return mergeObjects( + getTransfersById(liveTransfers).data ?? {}, + getTransfersById(restTransfers).data ?? {}, + (first, second) => maxBy([first, second], (f) => MustBigNumber(f.createdAtHeight).toNumber())! + ); +} diff --git a/src/abacus-ts/lib/mapLoadable.ts b/src/abacus-ts/lib/mapLoadable.ts new file mode 100644 index 000000000..b41c2e3ec --- /dev/null +++ b/src/abacus-ts/lib/mapLoadable.ts @@ -0,0 +1,8 @@ +import { Loadable } from './loadable'; + +export function mapLoadableData(load: Loadable, map: (obj: T) => R): Loadable { + return { + ...load, + data: load.data != null ? map(load.data) : undefined, + } as Loadable; +} diff --git a/src/abacus-ts/lib/mergeObjects.ts b/src/abacus-ts/lib/mergeObjects.ts new file mode 100644 index 000000000..50f40ac13 --- /dev/null +++ b/src/abacus-ts/lib/mergeObjects.ts @@ -0,0 +1,21 @@ +type SimpleMap = { [key: string]: T }; +export function mergeObjects(one: SimpleMap, two: SimpleMap, merge: (a: T, b: T) => T) { + const finalObj: SimpleMap = {}; + + [...Object.keys(one), ...Object.keys(two)].forEach((key) => { + if (finalObj[key] != null) { + return; + } + const obj = one[key]; + const otherObj = two[key]; + if (obj != null && otherObj != null) { + finalObj[key] = merge(obj, otherObj); + } else if (obj == null && otherObj == null) { + // do nothing + } else { + // we know one of them is non-null + finalObj[key] = (obj ?? otherObj)!; + } + }); + return finalObj; +}