-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Will Cory
authored and
Will Cory
committed
Jul 12, 2023
1 parent
6431ffb
commit 06954fe
Showing
2 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { vi, test, expect, beforeEach } from 'vitest' | ||
import { baseFee, decimals, gasPrice, getL1Fee, getL1GasUsed, l1BaseFee, overhead, scalar, version } from './estimateGas' | ||
|
||
// https://optimistic.etherscan.io/tx/0xceb34708f1de2ea2336dbdd81ca2cb7b12ec2ab6adc86a0d7d81c8c4416f81bb | ||
const data = '0x5c19a95c00000000000000000000000046abfe1c972fca43766d6ad70e1c1df72f4bb4d1' | ||
|
||
const chainConfig = | ||
{ | ||
chainId: 10, | ||
rpcUrl: process.env.VITE_L2_RPC_URL ?? 'https://mainnet.optimism.io', | ||
} as const | ||
|
||
const blockConfig = { | ||
blockNumber: BigInt(106773236), | ||
} | ||
|
||
const params = { ...chainConfig, ...blockConfig }; | ||
|
||
beforeEach(() => { | ||
vi.resetAllMocks() | ||
}) | ||
|
||
test('baseFee should return the correct result', async () => { | ||
expect(await baseFee(params)).toMatchInlineSnapshot('64n') | ||
}) | ||
|
||
test('decimals should return the correct result', async () => { | ||
expect(await decimals(params)).toMatchInlineSnapshot('6n') | ||
}) | ||
|
||
test('gasPrice should return the correct result', async () => { | ||
expect(await gasPrice(params)).toMatchInlineSnapshot('64n') | ||
}) | ||
|
||
test('getL1Fee should return the correct result', async () => { | ||
expect(await getL1Fee(data, params)).toMatchInlineSnapshot('15860541911298n') | ||
}) | ||
|
||
test('getL1GasUsed should return the correct result', async () => { | ||
expect(await getL1GasUsed(data, params)).toMatchInlineSnapshot('1708n') | ||
}) | ||
|
||
test('l1BaseFee should return the correct result', async () => { | ||
expect(await l1BaseFee(params)).toMatchInlineSnapshot('13576069538n') | ||
}) | ||
|
||
test('overhead should return the correct result', async () => { | ||
expect(await overhead(params)).toMatchInlineSnapshot('188n') | ||
}) | ||
|
||
test('scalar should return the correct result', async () => { | ||
expect(await scalar(params)).toMatchInlineSnapshot('684000n') | ||
}) | ||
|
||
test('version should return the correct result', async () => { | ||
expect(await version(params)).toMatchInlineSnapshot('"1.0.0"') | ||
}) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { gasPriceOracleABI, gasPriceOracleAddress } from "./constants" | ||
import { getContract, createPublicClient, http, BlockTag } from 'viem' | ||
import * as chains from 'viem/chains' | ||
|
||
|
||
type Bytes = `0x${string}` | ||
|
||
// Generated addresses don't generate mainnet at this moment | ||
type BlockOptions = { | ||
blockNumber?: bigint | undefined | ||
blockTag?: BlockTag | undefined | ||
} | ||
|
||
type ProviderOptions = { | ||
chainId: keyof typeof gasPriceOracleAddress | ||
rpcUrl?: string | undefined | ||
nativeCurrency?: chains.Chain['nativeCurrency'] | ||
} | { | ||
chainId: number | ||
rpcUrl: string | ||
nativeCurrency?: chains.Chain['nativeCurrency'] | ||
} | ||
|
||
const warnAboutFetch = () => { | ||
if (typeof fetch === 'undefined') { | ||
console.error('No fetch implementation found. Please provide a fetch polyfill. This can be done in NODE by passing in NODE_OPTIONS=--experimental-fetch or by using the isomorphic-fetch npm package') | ||
} | ||
} | ||
|
||
const getL2Client = ({ chainId, rpcUrl, nativeCurrency }: ProviderOptions) => { | ||
warnAboutFetch() | ||
const viemChain = Object.values(chains)?.find(chain => chain.id === chainId) | ||
const rpcUrls = rpcUrl ? { default: { http: [rpcUrl] }, public: { http: [rpcUrl] } } : viemChain?.rpcUrls | ||
if (!rpcUrls) { | ||
throw new Error(`No rpcUrls found for chainId ${chainId}. Please explicitly provide one`) | ||
} | ||
return createPublicClient({ | ||
chain: { | ||
id: chainId, | ||
name: viemChain?.name ?? 'op-chain', | ||
nativeCurrency: nativeCurrency ?? viemChain?.nativeCurrency ?? chains.optimism.nativeCurrency, | ||
network: viemChain?.network ?? 'Unknown OP Chain', | ||
rpcUrls, | ||
explorers: (viemChain as typeof chains.optimism)?.blockExplorers ?? chains.optimism.blockExplorers, | ||
}, | ||
transport: http(rpcUrl ?? chains[chainId].rpcUrls.public.http[0]), | ||
}) | ||
} | ||
|
||
const getGasPriceOracleContract = (params: ProviderOptions) => { | ||
return getContract({ | ||
address: gasPriceOracleAddress['420'], | ||
abi: gasPriceOracleABI, | ||
publicClient: getL2Client(params) | ||
}) | ||
} | ||
|
||
export type GasPriceOracleOptions = BlockOptions & ProviderOptions | ||
|
||
export const baseFee = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.baseFee(params) | ||
} | ||
|
||
export const decimals = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.decimals(params) | ||
} | ||
|
||
export const gasPrice = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.gasPrice(params) | ||
} | ||
|
||
export const getL1Fee = (data: Bytes, params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.getL1Fee([data], params) | ||
} | ||
|
||
export const getL1GasUsed = (data: Bytes, params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.getL1GasUsed([data], params) | ||
} | ||
|
||
export const l1BaseFee = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.l1BaseFee(params) | ||
} | ||
|
||
export const overhead = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.overhead(params) | ||
} | ||
|
||
export const scalar = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.scalar(params) | ||
} | ||
|
||
export const version = (params: GasPriceOracleOptions) => { | ||
const contract = getGasPriceOracleContract(params) | ||
return contract.read.version(params) | ||
} | ||
|