Skip to content

Commit

Permalink
create erc20 custom resolver with erc20StateByDay
Browse files Browse the repository at this point in the history
  • Loading branch information
apexearth committed Jul 26, 2024
1 parent 349fa0d commit 5e08410
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
116 changes: 116 additions & 0 deletions src/server-extension/erc20.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { GraphQLResolveInfo } from 'graphql'
import { Arg, Field, Info, Int, ObjectType, Query, Resolver } from 'type-graphql'
import { EntityManager } from 'typeorm'

@ObjectType()
export class ERC20StateByDay {
@Field(() => String, { nullable: false })
chainId!: number
@Field(() => String, { nullable: false })
address!: string
@Field(() => Date, { nullable: false })
day!: Date
@Field(() => BigInt, { nullable: false })
totalSupply!: bigint
@Field(() => Int, { nullable: false })
holderCount!: number

constructor(props: Partial<ERC20StateByDay>) {
Object.assign(this, props)
}
}

@Resolver()
export class ERC20Resolver {
constructor(private tx: () => Promise<EntityManager>) {}

@Query(() => [ERC20StateByDay])
async erc20StateByDay(
@Arg('address', () => String, { nullable: false }) address: string,
@Arg('from', () => String, { nullable: false }) from: string,
@Arg('to', () => String, { nullable: true }) to: string | null,
@Info() info: GraphQLResolveInfo,
): Promise<ERC20StateByDay[]> {
const manager = await this.tx()
const results = await manager.query(
`
WITH RECURSIVE date_series AS (
SELECT
DATE_TRUNC('day', $2::timestamp) AS day
UNION
SELECT
day + INTERVAL '1 day'
FROM
date_series
WHERE
day + INTERVAL '1 day' <= COALESCE($3::timestamp, NOW())
),
latest_daily_data AS (
SELECT DISTINCT ON (DATE_TRUNC('day', timestamp))
DATE_TRUNC('day', timestamp) AS day,
chain_id,
address,
total_supply,
holder_count
FROM
erc20_state
WHERE
address = $1
AND timestamp >= $2
AND ($3::timestamp IS NULL OR timestamp <= $3)
ORDER BY
DATE_TRUNC('day', timestamp), timestamp DESC
),
data_with_gaps AS (
SELECT
ds.day,
ldd.chain_id,
ldd.address,
ldd.total_supply,
ldd.holder_count
FROM
date_series ds
LEFT JOIN
latest_daily_data ldd ON ds.day = ldd.day
),
filled_data AS (
SELECT
day,
chain_id,
address,
total_supply,
holder_count,
COALESCE(total_supply, LAG(total_supply) OVER (PARTITION BY address ORDER BY day)) AS filled_total_supply,
COALESCE(holder_count, LAG(holder_count) OVER (PARTITION BY address ORDER BY day)) AS filled_holder_count
FROM
data_with_gaps
)
SELECT
chain_id,
address,
day,
filled_total_supply AS total_supply,
filled_holder_count AS holder_count
FROM
filled_data
WHERE
chain_id is not null
ORDER BY
day;
`,
[address, from, to],
)

return results.map(
(row: any) =>
new ERC20StateByDay({
chainId: row.chain_id,
address: row.address,
day: row.day,
totalSupply: BigInt(row.total_supply),
holderCount: row.holder_count,
}),
)
}
}
1 change: 1 addition & 0 deletions src/server-extension/resolvers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ import 'tsconfig-paths/register'

export { OGNStatsResolver } from '../ogn-stats'
export { StrategyResolver } from '../strategies'
export { ERC20Resolver } from '../erc20'

0 comments on commit 5e08410

Please sign in to comment.