From 4b6041f66711a254487ceac9ea3dda773d39cd14 Mon Sep 17 00:00:00 2001 From: Lucemans Date: Tue, 19 Mar 2024 14:37:32 +0000 Subject: [PATCH] I hate gas math. Javascript ints suck --- web/src/App.tsx | 78 ++++++++++++++++++++++++-- web/src/main.tsx | 24 +++++++- web/src/txHistory/TransactionEntry.tsx | 19 ++++--- web/src/utils/ethUsd.ts | 15 ++++- web/src/utils/gas.ts | 10 ---- web/src/utils/gasMagic.ts | 12 ++++ 6 files changed, 130 insertions(+), 28 deletions(-) delete mode 100644 web/src/utils/gas.ts create mode 100644 web/src/utils/gasMagic.ts diff --git a/web/src/App.tsx b/web/src/App.tsx index 00f2995..aad0b01 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react'; +import { BsFuelPump } from 'react-icons/bs'; import useSWR from 'swr'; import { getTransactions } from './etherscan/getTransactions'; @@ -8,7 +9,9 @@ import { AllMultiReturnTypes, decodeTransaction, } from './utils/decodeTransaction'; +import { useEthUsd } from './utils/ethUsd'; import { formatThousands } from './utils/formatThousands'; +import { gasPriceMagic } from './utils/gasMagic'; const contractAddress = '0xFC0a4A934410F34A9bb8b4F28bEd6b960C943a7E'; @@ -35,6 +38,12 @@ export const App = () => { return aggregateTotals(decodedTransactions) as Aggregates; }, [decodedTransactions]); + const { data: currentUSDCPrice } = useEthUsd(); + + console.log({ currentUSDCPrice }); + + const gasPrice = 30n; + return (
@@ -63,8 +72,27 @@ export const App = () => {
Commit Fee
{totals?.commitAverage ? ( -
- {formatThousands(totals.commitAverage)} +
+
+ {formatThousands(totals.commitAverage)} +
+ {currentUSDCPrice ? ( +
+
+ + {gasPrice.toString()} +
+
+ ~{' '} + {gasPriceMagic( + totals.commitAverage, + gasPrice, + currentUSDCPrice + )}{' '} + USD +
+
+ ) : undefined}
) : (
Loading...
@@ -73,8 +101,27 @@ export const App = () => {
Registration Fee
{totals?.registerAverage ? ( -
- {formatThousands(totals.registerAverage)} +
+
+ {formatThousands(totals.registerAverage)} +
+ {currentUSDCPrice ? ( +
+
+ + {gasPrice.toString()} +
+
+ ~{' '} + {gasPriceMagic( + totals.registerAverage, + gasPrice, + currentUSDCPrice + )}{' '} + USD +
+
+ ) : undefined}
) : (
Loading...
@@ -83,8 +130,27 @@ export const App = () => {
Renewal Fee
{totals?.renewAverage ? ( -
- {formatThousands(totals.renewAverage)} +
+
+ {formatThousands(totals.renewAverage)} +
+ {currentUSDCPrice ? ( +
+
+ + {gasPrice.toString()} +
+
+ ~{' '} + {gasPriceMagic( + totals.renewAverage, + gasPrice, + currentUSDCPrice + )}{' '} + USD +
+
+ ) : undefined}
) : (
Loading...
diff --git a/web/src/main.tsx b/web/src/main.tsx index 23a8157..8de5b7f 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -2,6 +2,7 @@ import './globals.css'; import React from 'react'; import ReactDOM from 'react-dom/client'; +import { SWRConfig } from 'swr'; import { App } from './App'; @@ -10,8 +11,29 @@ BigInt.prototype.toJSON = function () { return this.toString(); }; +function localStorageProvider() { + // When initializing, we restore the data from `localStorage` into a map. + const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]')); + + // Before unloading the app, we write back all the data into `localStorage`. + window.addEventListener('beforeunload', () => { + const appCache = JSON.stringify(Array.from(map.entries())); + + localStorage.setItem('app-cache', appCache); + }); + + // We still use the map for write & read for performance. + return map; +} + ReactDOM.createRoot(document.querySelector('#root') as HTMLElement).render( - + + + ); diff --git a/web/src/txHistory/TransactionEntry.tsx b/web/src/txHistory/TransactionEntry.tsx index 0daffb1..878cbd7 100644 --- a/web/src/txHistory/TransactionEntry.tsx +++ b/web/src/txHistory/TransactionEntry.tsx @@ -11,7 +11,6 @@ import { } from '../utils/decodeTransaction'; import { useEthUsd } from '../utils/ethUsd'; import { formatThousands } from '../utils/formatThousands'; -import { gasToEth } from '../utils/gas'; export const TransactionEntry: FC<{ tx: AllMultiReturnTypes }> = ({ tx }) => { const actionLabel = deriveLabelFromFunctionName(tx.functionName, tx.tx.to); @@ -65,18 +64,22 @@ export const TransactionEntry: FC<{ tx: AllMultiReturnTypes }> = ({ tx }) => {
{formatThousands(BigInt(tx.tx.gasUsed))}
- {ethUsd.data && ( + {ethUsd.data ? (
- {( - ethUsd.data * - gasToEth( - BigInt(tx.tx.gasUsed), - BigInt(tx.tx.gasPrice) + {Number( + Number( + (ethUsd.data * + Number( + (BigInt(tx.tx.gasUsed) * + BigInt(tx.tx.gasPrice)) / + 1_000_000_000_000_000n + )) / + 1_000_000 ) ).toFixed(2)}{' '} USD
- )} + ) : undefined}
diff --git a/web/src/utils/ethUsd.ts b/web/src/utils/ethUsd.ts index d4ab411..a0f017b 100644 --- a/web/src/utils/ethUsd.ts +++ b/web/src/utils/ethUsd.ts @@ -1,7 +1,7 @@ import useSWR from 'swr'; -export const useEthUsd = (timestamp: number) => { - const date = new Date(timestamp); +export const useEthUsd = (timestamp?: number) => { + const date = timestamp ? new Date(timestamp) : new Date(Date.now()); const year = date.getUTCFullYear(); const month = date.getUTCMonth() + 1; const day = date.getUTCDate(); @@ -10,12 +10,21 @@ export const useEthUsd = (timestamp: number) => { const dateString = `${day}-${month}-${year}`; return useSWR(['ethUsd', dateString], async () => { + const x = localStorage.getItem('usdc-eth-' + dateString); + + if (x) return Number(x); + const response = await fetch( `https://api.coingecko.com/api/v3/coins/ethereum/history?date=${dateString}` ); const data = await response.json(); - return data.market_data.current_price.usd as number; + // USDC per 1000 ETH + const value = Number(data.market_data.current_price.usd) * 1000; + + localStorage.setItem('usdc-eth-' + dateString, value.toString()); + + return Number(value); }); }; diff --git a/web/src/utils/gas.ts b/web/src/utils/gas.ts deleted file mode 100644 index 991e933..0000000 --- a/web/src/utils/gas.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const gasToEth = (gas: bigint, gasPrice: bigint) => { - console.log( - gas, - gasPrice, - gas * gasPrice, - Number(gas * gasPrice) / 1_000_000_000_000_000_000 - ); - - return Number(gas * gasPrice) / 1_000_000_000_000_000_000; -}; diff --git a/web/src/utils/gasMagic.ts b/web/src/utils/gasMagic.ts new file mode 100644 index 0000000..1574cd4 --- /dev/null +++ b/web/src/utils/gasMagic.ts @@ -0,0 +1,12 @@ +export const gasPriceMagic = ( + gas: bigint, + gasPrice: bigint, + ethUSDC: number +) => { + return ( + Number( + BigInt(Math.round(Number(gas * gasPrice * 1000n) * ethUSDC)) / + 1_000_000n + ) / 1_000_000_000 + ).toPrecision(3); +};