Skip to content

Commit 0db98d3

Browse files
committed
db update
1 parent 1fe989a commit 0db98d3

File tree

8 files changed

+55
-156
lines changed

8 files changed

+55
-156
lines changed

src/components/charts/trend.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ export function TrendChart(props: Props) {
2626
},
2727
}
2828
const series = [
29-
{
30-
name: 'median',
31-
data: props.data.map((item) => Math.round(item.median * 100) / 100),
32-
},
3329
{
3430
name: 'baseFee',
3531
data: props.data.map((item) => Math.round(item.baseFee * 100) / 100),

src/components/featured.module.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
}
3131
}
3232

33+
.double {
34+
grid-template-columns: 1fr 1fr;
35+
36+
@media (max-width: $screen-640) {
37+
grid-template-columns: 1fr;
38+
}
39+
}
40+
3341
.rows {
3442
display: grid;
3543
gap: $gap-16;

src/components/featured.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ interface Props {
88
type?: 'grid' | 'rows'
99
className?: string
1010
children: ReactNode
11+
double?: boolean
1112
}
1213

1314
export function Featured(props: Props) {
1415
let className = `${styles.container}`
1516
if (props.className) className += ` ${props.className}`
1617
let type = styles.grid
18+
if (props.double) type += ` ${styles.double}`
1719
if (props.type) type = styles[props.type]
1820

1921
return (

src/hooks/useGasPrice.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export function useGasPrice(network: string = '', interval: number = 12000) {
2424
try {
2525
const provider = !network ? getDefaultProvider() : GetRpcProvider(network as any)
2626
const feeData = await provider.getFeeData()
27-
console.log('FEE DATA', feeData)
2827

2928
if (feeData.gasPrice && feeData.maxPriorityFeePerGas) {
3029
const gasPrice = Math.round(Number(formatUnits(feeData.gasPrice, 'gwei')) * 100) / 100

src/pages/gas.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default function Index(props: Props) {
3535
<SEO title={title} divider="⛽" description="Monitor and track the Ethereum gas price to reduce transaction fees save money." />
3636
<TopnavLayout className={styles.container} title="Ethereum Gas tracker" action={{ href: '/gas/api', text: 'Get API Access' }}>
3737
<section>
38-
<Featured className={styles.featured}>
38+
<Featured className={styles.featured} double>
3939
<Panel type="primary" fill stretch>
4040
<div style={{ padding: '8px' }}>
4141
<h4>⛽ Current</h4>
@@ -49,18 +49,7 @@ export default function Index(props: Props) {
4949
<div style={{ padding: '8px' }}>
5050
<h4>🕘 Avg/last hour</h4>
5151
<br />
52-
<span>baseFee: {Math.round(props.gasData.lastHour.baseFee * 100) / 100}</span>
53-
<br />
54-
<span>median: {Math.round(props.gasData.lastHour.median * 100) / 100}</span>
55-
</div>
56-
</Panel>
57-
<Panel type="neutral" stretch>
58-
<div style={{ padding: '8px' }}>
59-
<h4>📅 Avg/24 hours</h4>
60-
<br />
61-
<span>baseFee: {Math.round(props.gasData.lastDay.baseFee * 100) / 100}</span>
62-
<br />
63-
<span>median: {Math.round(props.gasData.lastDay.median * 100) / 100}</span>
52+
<span>baseFee: {props.gasData.lastHour}</span>
6453
</div>
6554
</Panel>
6655
</Featured>
@@ -96,12 +85,18 @@ export default function Index(props: Props) {
9685
<li>
9786
<Link href="/gas">Ethereum Gas Tracker</Link>
9887
</li>
88+
<li>
89+
<Link href="/gas/arbitrum">Arbitrum Gas Tracker</Link>
90+
</li>
9991
<li>
10092
<Link href="/gas/optimism">Optimism Gas Tracker</Link>
10193
</li>
10294
<li>
10395
<Link href="/gas/polygon">Polygon Gas Tracker</Link>
10496
</li>
97+
<li>
98+
<Link href="/gas/base">Base Gas Tracker</Link>
99+
</li>
105100
</ul>
106101
</article>
107102

@@ -155,13 +150,13 @@ export const getStaticProps: GetStaticProps<Props> = async () => {
155150
const categories = await service.GetCategories()
156151

157152
const gasData = await GetGasData()
158-
const hourlyAverages = await GetAverage('hour', 168)
153+
const averages = await GetAverage('hour', 168)
159154

160155
return {
161156
props: {
162157
categories,
163158
gasData,
164-
heatmap: hourlyAverages ?? [],
159+
heatmap: averages ?? [],
165160
},
166161
revalidate: DEFAULT_REVALIDATE_PERIOD,
167162
}

src/pages/gas/[network].tsx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function Index(props: Props) {
4444
<SEO title={title} divider="⛽" description={`Monitor and track the ${networkName} gas price to reduce transaction fees save money.`} />
4545
<TopnavLayout className={styles.container} title={defaultTitle} action={{ href: '/gas/api', text: 'Get API Access' }}>
4646
<section>
47-
<Featured className={styles.featured}>
47+
<Featured className={styles.featured} double>
4848
<Panel type="primary" fill stretch>
4949
<div style={{ padding: '8px' }}>
5050
<h4>⛽ Current</h4>
@@ -58,18 +58,7 @@ export default function Index(props: Props) {
5858
<div style={{ padding: '8px' }}>
5959
<h4>🕘 Avg/last hour</h4>
6060
<br />
61-
<span>baseFee: {Math.round(props.gasData.lastHour.baseFee * 100) / 100}</span>
62-
<br />
63-
<span>median: {Math.round(props.gasData.lastHour.median * 100) / 100}</span>
64-
</div>
65-
</Panel>
66-
<Panel type="neutral" stretch>
67-
<div style={{ padding: '8px' }}>
68-
<h4>📅 Avg/24 hours</h4>
69-
<br />
70-
<span>baseFee: {Math.round(props.gasData.lastDay.baseFee * 100) / 100}</span>
71-
<br />
72-
<span>median: {Math.round(props.gasData.lastDay.median * 100) / 100}</span>
61+
<span>baseFee: {props.gasData.lastHour}</span>
7362
</div>
7463
</Panel>
7564
</Featured>
@@ -105,15 +94,18 @@ export default function Index(props: Props) {
10594
<li>
10695
<Link href="/gas">Ethereum Gas Tracker</Link>
10796
</li>
108-
{/* <li>
97+
<li>
10998
<Link href="/gas/arbitrum">Arbitrum Gas Tracker</Link>
110-
</li> */}
99+
</li>
111100
<li>
112101
<Link href="/gas/optimism">Optimism Gas Tracker</Link>
113102
</li>
114103
<li>
115104
<Link href="/gas/polygon">Polygon Gas Tracker</Link>
116105
</li>
106+
<li>
107+
<Link href="/gas/base">Base Gas Tracker</Link>
108+
</li>
117109
</ul>
118110
</article>
119111

@@ -171,9 +163,12 @@ export const getStaticPaths: GetStaticPaths = async () => {
171163
{
172164
params: { network: 'optimism' },
173165
},
174-
// {
175-
// params: { network: 'arbitrum' },
176-
// },
166+
{
167+
params: { network: 'arbitrum' },
168+
},
169+
{
170+
params: { network: 'base' },
171+
},
177172
],
178173
fallback: false,
179174
}
@@ -184,7 +179,7 @@ export const getStaticProps: GetStaticProps<Props, Params> = async (context) =>
184179
const service = new MarkdownContentService()
185180
const categories = await service.GetCategories()
186181

187-
if (!network || !['polygon', 'optimism'].includes(network)) {
182+
if (!network || !['polygon', 'optimism', 'base', 'arbitrum'].includes(network)) {
188183
return {
189184
props: null,
190185
notFound: true,

src/services/indexer.ts

Lines changed: 20 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,42 @@
1-
import * as dotenv from 'dotenv'
2-
import { createClient } from '@supabase/supabase-js'
3-
import { getMin, getMax, getAverage, getMedian, toRoundedGwei, getEthPrice } from 'utils/gas'
41
import { GasFee } from 'types/gas'
5-
import { GetRpcProvider } from 'utils/providers'
6-
7-
dotenv.config()
82

93
const defaultBlockLimit = 10
10-
export type NETWORKS = 'mainnet' | 'polygon' | 'optimism' | 'arbitrum'
11-
12-
if (!process.env.SUPABASE_URL || !process.env.SUPABASE_KEY) {
13-
console.warn('SUPABASE_URL or SUPABASE_KEY env variables are not set.')
14-
}
15-
16-
if (!process.env.INFURA_KEY) {
17-
console.warn('INFURA_KEY env variable is not set.')
18-
}
19-
20-
if (!process.env.NEXT_PUBLIC_ALCHEMY_API_KEY) {
21-
console.warn('NEXT_PUBLIC_ALCHEMY_API_KEY env variable is not set.')
22-
}
23-
24-
export async function Index(network: NETWORKS = 'mainnet') {
25-
console.log(`[${network}] Start indexing..`)
26-
27-
const db = CreateDbClient()
28-
const provider = GetRpcProvider(network)
29-
30-
const currentBlock = await provider.getBlockNumber()
31-
const lastProcessedBlock = await db.from(network).select('*').order('blockNr', { ascending: false }).limit(1)
32-
const runUntil =
33-
lastProcessedBlock.data && lastProcessedBlock.data.length > 0 ? lastProcessedBlock.data[0].blockNr : null || currentBlock - defaultBlockLimit
34-
console.log(`[${network}] Process blocks # ${runUntil} / ${currentBlock}`)
35-
36-
let blockNr = currentBlock
37-
while (blockNr >= runUntil) {
38-
console.log(`[${network}] # ${blockNr}`)
39-
40-
const block = await provider.getBlockWithTransactions(blockNr)
41-
const fees = block.transactions.map((i) => toRoundedGwei(i.maxFeePerGas)).filter((i) => i > 0)
42-
const ethPrice = await getEthPrice()
43-
44-
const record = {
45-
blockNr: block.number,
46-
baseFee: toRoundedGwei(block.baseFeePerGas),
47-
gasLimit: block.gasLimit.toNumber(),
48-
gasUsed: block.gasUsed.toNumber(),
49-
txCount: block.transactions.length,
50-
min: getMin(fees),
51-
max: getMax(fees),
52-
avg: getAverage(fees),
53-
median: getMedian(fees),
54-
ethPrice: ethPrice,
55-
}
56-
57-
// console.log(`[${network}] Add to db`, record)
58-
const response = await db.from(network).upsert([record])
59-
if (response.error) {
60-
console.log(`[${network}] Unable to save block # ${blockNr}`, record)
61-
throw new Error(response.error.message)
62-
}
63-
64-
blockNr--
65-
}
66-
67-
console.log(`[${network}] Completed.`)
68-
return
69-
}
704

71-
export async function Cleanup(network: NETWORKS = 'mainnet') {
72-
console.log(`[${network}] Start cleanup..`)
73-
74-
const db = CreateDbClient()
75-
try {
76-
// delete all records where created_at is older than 14 days
77-
const since = new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString()
78-
console.log(`[${network}] Delete records older than ${since}`)
79-
const { data, error } = await db.from(network).delete().lte('created_at', since)
80-
81-
if (error) {
82-
console.error('Error:', error)
83-
throw new Error(error.message)
84-
}
85-
86-
console.log('Data deleted!')
87-
return data
88-
} catch (error) {
89-
console.error('Error:', error)
90-
}
91-
}
5+
export type NETWORKS = 'mainnet' | 'polygon' | 'optimism' | 'arbitrum' | 'base'
926

937
export async function GetGasData(network: NETWORKS = 'mainnet') {
948
console.log('Get GasData', network)
95-
const daily = await GetAverage('day', 1, network)
96-
const hourly = await GetAverage('hour', 24, network)
979

98-
if (!daily || daily.length === 0) {
99-
throw new Error('Unable to fetch daily average')
10+
try {
11+
const res = await fetch(`https://www.ethgastracker.com/api/gas/history/${network}`)
12+
const body = await res.json()
13+
const blocks = body.data.blocks
14+
const average = blocks.map((i: GasFee) => i.baseFee).reduce((a: number, b: number) => a + b, 0) / blocks.length
15+
16+
return {
17+
lastHour: Math.round(average * 100) / 100,
18+
fees: body.data.blocks,
19+
}
10020
}
101-
if (!hourly || hourly.length === 0) {
102-
throw new Error('Unable to fetch hourly average')
21+
catch (error) {
22+
console.error('Error:', error)
10323
}
10424

10525
return {
106-
lastDay: daily[0],
107-
lastHour: hourly[0],
108-
fees: hourly,
26+
lastHour: 0,
27+
fees: [],
10928
}
11029
}
11130

11231
export async function GetAverage(period: 'hour' | 'day', limit: number = 24, network: NETWORKS = 'mainnet') {
11332
console.log(`[${network}] Get average by ${period}`)
11433

115-
const db = CreateDbClient()
116-
11734
try {
118-
const { data, error } = await db.from(`gasdata_${network}_${period}`).select('*').limit(limit)
119-
120-
if (error) {
121-
console.error('Error:', error)
122-
throw new Error(error.message)
123-
}
124-
125-
return data as GasFee[]
126-
} catch (error) {
127-
console.error('Error:', error)
35+
const res = await fetch(`https://www.ethgastracker.com/api/gas/average/${network}`)
36+
const body = await res.json()
37+
return body.data.data
12838
}
129-
}
130-
131-
export function CreateDbClient() {
132-
if (!process.env.SUPABASE_URL || !process.env.SUPABASE_KEY) {
133-
throw new Error('SUPABASE_URL or SUPABASE_KEY env variables are not set.')
39+
catch (error) {
40+
console.error('Error:', error)
13441
}
135-
136-
return createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)
13742
}

src/types/gas.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ export interface Heatmap {
1414
}
1515

1616
export interface GasData {
17-
lastDay: GasFee
18-
lastHour: GasFee
17+
lastHour: number
1918
fees: GasFee[]
2019
}
2120

0 commit comments

Comments
 (0)