From d96b26d24d8058b9828962f97d92515540f41508 Mon Sep 17 00:00:00 2001 From: Tair Asim Date: Fri, 24 Dec 2021 09:28:22 +0100 Subject: [PATCH] feat: Add dynamic gas fee calculations (#76) - Add documentation for dynamic gas cost and gas refunds - Add a gas estimator to compute fees based on Inputs and Common params - Change "Static gas" column to "Minimum gas" to avoid misleading 0 cost - Use Input stack variable names more consistently in the doc - Extend opcodes.json with dynamicFee definition of user inputs - Add support for opcode specific dynamic docs with variables from Common gasPrices param - Show dynamic gas fee tooltip only when it's active in the selected fork UI: - Add focus state on the input fields Misc: - Upgrade to NextJS 12 with Webpack 5 - Get rid of browserify with global ethereumjs objects - Simplify lookup of table's opcodes object - Fix saving of selected fork setting value - Fix setting common chain and hardfork Closes #57 #67 #85 --- .eslintrc.js | 1 + .gitignore | 1 + components/ChainSelector.tsx | 8 +- components/Editor/index.tsx | 8 +- components/Reference/DocRow.tsx | 86 ++- components/Reference/DynamicFee.tsx | 123 ++++ components/Reference/Filters.tsx | 1 + components/Reference/data.tsx | 4 +- components/Reference/index.tsx | 70 +- components/layouts/Home.tsx | 3 - components/ui/Button.tsx | 3 +- components/ui/Doc.tsx | 10 +- components/ui/Heading.tsx | 4 +- components/ui/Input.tsx | 43 +- components/ui/Message.tsx | 12 +- components/ui/StackBox.tsx | 4 +- context/ethereumContext.tsx | 76 ++- docs/ARCHITECTURE.md | 20 +- docs/opcodes/01.mdx | 8 +- docs/opcodes/02.mdx | 8 +- docs/opcodes/03.mdx | 8 +- docs/opcodes/04.mdx | 8 +- docs/opcodes/05.mdx | 8 +- docs/opcodes/06.mdx | 8 +- docs/opcodes/07.mdx | 8 +- docs/opcodes/08.mdx | 10 +- docs/opcodes/09.mdx | 10 +- docs/opcodes/0A.mdx | 8 +- docs/opcodes/0A/homestead.mdx | 6 + docs/opcodes/0B.mdx | 8 +- docs/opcodes/10.mdx | 8 +- docs/opcodes/11.mdx | 8 +- docs/opcodes/12.mdx | 8 +- docs/opcodes/13.mdx | 8 +- docs/opcodes/14.mdx | 8 +- docs/opcodes/15.mdx | 6 +- docs/opcodes/16.mdx | 8 +- docs/opcodes/17.mdx | 8 +- docs/opcodes/18.mdx | 8 +- docs/opcodes/19.mdx | 6 +- docs/opcodes/1A.mdx | 8 +- docs/opcodes/1B.mdx | 8 +- docs/opcodes/1C.mdx | 8 +- docs/opcodes/1D.mdx | 8 +- docs/opcodes/20.mdx | 8 +- docs/opcodes/20/homestead.mdx | 8 + docs/opcodes/30.mdx | 4 +- docs/opcodes/31.mdx | 6 +- docs/opcodes/31/berlin.mdx | 3 + docs/opcodes/32.mdx | 4 +- docs/opcodes/33.mdx | 4 +- docs/opcodes/34.mdx | 4 +- docs/opcodes/35.mdx | 6 +- docs/opcodes/36.mdx | 4 +- docs/opcodes/37.mdx | 8 +- docs/opcodes/37/homestead.mdx | 8 + docs/opcodes/38.mdx | 4 +- docs/opcodes/39.mdx | 8 +- docs/opcodes/39/homestead.mdx | 8 + docs/opcodes/3A.mdx | 4 +- docs/opcodes/3B.mdx | 6 +- docs/opcodes/3B/berlin.mdx | 3 + docs/opcodes/3C.mdx | 10 +- docs/opcodes/3C/berlin.mdx | 9 + docs/opcodes/3C/homestead.mdx | 8 + docs/opcodes/3D.mdx | 4 +- docs/opcodes/3E.mdx | 8 +- docs/opcodes/3E/homestead.mdx | 8 + docs/opcodes/3F.mdx | 6 +- docs/opcodes/3F/berlin.mdx | 3 + docs/opcodes/40.mdx | 6 +- docs/opcodes/41.mdx | 4 +- docs/opcodes/42.mdx | 4 +- docs/opcodes/43.mdx | 4 +- docs/opcodes/44.mdx | 4 +- docs/opcodes/45.mdx | 4 +- docs/opcodes/46.mdx | 4 +- docs/opcodes/47.mdx | 4 +- docs/opcodes/48.mdx | 4 +- docs/opcodes/50.mdx | 4 +- docs/opcodes/51.mdx | 6 +- docs/opcodes/51/homestead.mdx | 6 + docs/opcodes/52.mdx | 6 +- docs/opcodes/52/homestead.mdx | 6 + docs/opcodes/53.mdx | 6 +- docs/opcodes/53/homestead.mdx | 6 + docs/opcodes/54.mdx | 6 +- docs/opcodes/54/berlin.mdx | 3 + docs/opcodes/55.mdx | 6 +- docs/opcodes/55/berlin.mdx | 40 ++ docs/opcodes/55/constantinople.mdx | 32 + docs/opcodes/55/homestead.mdx | 7 + docs/opcodes/55/istanbul.mdx | 32 + docs/opcodes/55/petersburg.mdx | 7 + docs/opcodes/56.mdx | 8 +- docs/opcodes/57.mdx | 10 +- docs/opcodes/58.mdx | 6 +- docs/opcodes/59.mdx | 6 +- docs/opcodes/5A.mdx | 4 +- docs/opcodes/60.mdx | 4 +- docs/opcodes/61.mdx | 4 +- docs/opcodes/62.mdx | 4 +- docs/opcodes/63.mdx | 4 +- docs/opcodes/64.mdx | 4 +- docs/opcodes/65.mdx | 4 +- docs/opcodes/66.mdx | 4 +- docs/opcodes/67.mdx | 4 +- docs/opcodes/68.mdx | 4 +- docs/opcodes/69.mdx | 4 +- docs/opcodes/6A.mdx | 4 +- docs/opcodes/6B.mdx | 4 +- docs/opcodes/6C.mdx | 4 +- docs/opcodes/6D.mdx | 4 +- docs/opcodes/6E.mdx | 4 +- docs/opcodes/6F.mdx | 4 +- docs/opcodes/70.mdx | 4 +- docs/opcodes/71.mdx | 4 +- docs/opcodes/72.mdx | 4 +- docs/opcodes/73.mdx | 4 +- docs/opcodes/74.mdx | 4 +- docs/opcodes/75.mdx | 4 +- docs/opcodes/76.mdx | 4 +- docs/opcodes/77.mdx | 4 +- docs/opcodes/78.mdx | 4 +- docs/opcodes/79.mdx | 4 +- docs/opcodes/7A.mdx | 4 +- docs/opcodes/7B.mdx | 4 +- docs/opcodes/7C.mdx | 4 +- docs/opcodes/7D.mdx | 4 +- docs/opcodes/7E.mdx | 4 +- docs/opcodes/7F.mdx | 4 +- docs/opcodes/80.mdx | 8 +- docs/opcodes/81.mdx | 12 +- docs/opcodes/82.mdx | 16 +- docs/opcodes/83.mdx | 20 +- docs/opcodes/84.mdx | 24 +- docs/opcodes/85.mdx | 28 +- docs/opcodes/86.mdx | 32 +- docs/opcodes/87.mdx | 36 +- docs/opcodes/88.mdx | 40 +- docs/opcodes/89.mdx | 44 +- docs/opcodes/8A.mdx | 48 +- docs/opcodes/8B.mdx | 52 +- docs/opcodes/8C.mdx | 56 +- docs/opcodes/8D.mdx | 60 +- docs/opcodes/8E.mdx | 64 +- docs/opcodes/8F.mdx | 68 +- docs/opcodes/90.mdx | 10 +- docs/opcodes/91.mdx | 14 +- docs/opcodes/92.mdx | 18 +- docs/opcodes/93.mdx | 22 +- docs/opcodes/94.mdx | 26 +- docs/opcodes/95.mdx | 30 +- docs/opcodes/96.mdx | 34 +- docs/opcodes/97.mdx | 38 +- docs/opcodes/98.mdx | 42 +- docs/opcodes/99.mdx | 46 +- docs/opcodes/9A.mdx | 50 +- docs/opcodes/9B.mdx | 54 +- docs/opcodes/9C.mdx | 58 +- docs/opcodes/9D.mdx | 62 +- docs/opcodes/9E.mdx | 66 +- docs/opcodes/9F.mdx | 70 +- docs/opcodes/A0.mdx | 6 +- docs/opcodes/A0/homestead.mdx | 7 + docs/opcodes/A1.mdx | 8 +- docs/opcodes/A1/homestead.mdx | 7 + docs/opcodes/A2.mdx | 10 +- docs/opcodes/A2/homestead.mdx | 7 + docs/opcodes/A3.mdx | 12 +- docs/opcodes/A3/homestead.mdx | 7 + docs/opcodes/A4.mdx | 14 +- docs/opcodes/A4/homestead.mdx | 7 + docs/opcodes/F0.mdx | 8 +- docs/opcodes/F0/berlin.mdx | 12 + docs/opcodes/F0/homestead.mdx | 10 + docs/opcodes/F1.mdx | 20 +- docs/opcodes/F1/berlin.mdx | 12 + docs/opcodes/F1/homestead.mdx | 11 + docs/opcodes/F1/spuriousDragon.mdx | 11 + docs/opcodes/F2.mdx | 20 +- docs/opcodes/F2/berlin.mdx | 11 + docs/opcodes/F2/homestead.mdx | 10 + docs/opcodes/F3.mdx | 6 +- docs/opcodes/F3/homestead.mdx | 6 + docs/opcodes/F4.mdx | 18 +- docs/opcodes/F4/berlin.mdx | 10 + docs/opcodes/F4/homestead.mdx | 9 + docs/opcodes/F5.mdx | 12 +- docs/opcodes/F5/berlin.mdx | 14 + docs/opcodes/F5/constantinople.mdx | 12 + docs/opcodes/FA.mdx | 20 +- docs/opcodes/FA/berlin.mdx | 10 + docs/opcodes/FA/homestead.mdx | 9 + docs/opcodes/FD.mdx | 10 +- docs/opcodes/FD/homestead.mdx | 6 + docs/opcodes/FE/homestead.mdx | 3 + docs/opcodes/FF.mdx | 4 +- docs/opcodes/FF/berlin.mdx | 3 + docs/opcodes/FF/spuriousDragon.mdx | 7 + docs/opcodes/FF/tangerineWhistle.mdx | 7 + lib/ethereum.js | 12 - next-env.d.ts | 1 - next.config.js | 15 + opcodes.json | 883 ++++++++++++++++++++++-- package.json | 27 +- pages/about.tsx | 180 ++++- pages/api/getDynamicDoc.ts | 14 + pages/index.tsx | 66 +- public/ethereum.min.js | 1 - tailwind.config.js | 1 + tsconfig.json | 19 +- types/index.ts | 22 +- util/gas.ts | 409 +++++++++++ yarn.lock | 976 ++++++++++----------------- 215 files changed, 3639 insertions(+), 1823 deletions(-) create mode 100644 components/Reference/DynamicFee.tsx create mode 100644 docs/opcodes/0A/homestead.mdx create mode 100644 docs/opcodes/20/homestead.mdx create mode 100644 docs/opcodes/31/berlin.mdx create mode 100644 docs/opcodes/37/homestead.mdx create mode 100644 docs/opcodes/39/homestead.mdx create mode 100644 docs/opcodes/3B/berlin.mdx create mode 100644 docs/opcodes/3C/berlin.mdx create mode 100644 docs/opcodes/3C/homestead.mdx create mode 100644 docs/opcodes/3E/homestead.mdx create mode 100644 docs/opcodes/3F/berlin.mdx create mode 100644 docs/opcodes/51/homestead.mdx create mode 100644 docs/opcodes/52/homestead.mdx create mode 100644 docs/opcodes/53/homestead.mdx create mode 100644 docs/opcodes/54/berlin.mdx create mode 100644 docs/opcodes/55/berlin.mdx create mode 100644 docs/opcodes/55/constantinople.mdx create mode 100644 docs/opcodes/55/homestead.mdx create mode 100644 docs/opcodes/55/istanbul.mdx create mode 100644 docs/opcodes/55/petersburg.mdx create mode 100644 docs/opcodes/A0/homestead.mdx create mode 100644 docs/opcodes/A1/homestead.mdx create mode 100644 docs/opcodes/A2/homestead.mdx create mode 100644 docs/opcodes/A3/homestead.mdx create mode 100644 docs/opcodes/A4/homestead.mdx create mode 100644 docs/opcodes/F0/berlin.mdx create mode 100644 docs/opcodes/F0/homestead.mdx create mode 100644 docs/opcodes/F1/berlin.mdx create mode 100644 docs/opcodes/F1/homestead.mdx create mode 100644 docs/opcodes/F1/spuriousDragon.mdx create mode 100644 docs/opcodes/F2/berlin.mdx create mode 100644 docs/opcodes/F2/homestead.mdx create mode 100644 docs/opcodes/F3/homestead.mdx create mode 100644 docs/opcodes/F4/berlin.mdx create mode 100644 docs/opcodes/F4/homestead.mdx create mode 100644 docs/opcodes/F5/berlin.mdx create mode 100644 docs/opcodes/F5/constantinople.mdx create mode 100644 docs/opcodes/FA/berlin.mdx create mode 100644 docs/opcodes/FA/homestead.mdx create mode 100644 docs/opcodes/FD/homestead.mdx create mode 100644 docs/opcodes/FE/homestead.mdx create mode 100644 docs/opcodes/FF/berlin.mdx create mode 100644 docs/opcodes/FF/spuriousDragon.mdx create mode 100644 docs/opcodes/FF/tangerineWhistle.mdx delete mode 100644 lib/ethereum.js create mode 100644 pages/api/getDynamicDoc.ts delete mode 100644 public/ethereum.min.js create mode 100644 util/gas.ts diff --git a/.eslintrc.js b/.eslintrc.js index a417c889..ead6bede 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -30,6 +30,7 @@ module.exports = { 'plugin:prettier/recommended', ], rules: { + curly: 'error', 'prettier/prettier': ['error', {}, { usePrettierrc: true }], 'react/prop-types': 'off', 'react/react-in-jsx-scope': 'off', diff --git a/.gitignore b/.gitignore index 1437c53f..35b7a4ac 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ # misc .DS_Store *.pem +tsconfig.tsbuildinfo # debug npm-debug.log* diff --git a/components/ChainSelector.tsx b/components/ChainSelector.tsx index bf637090..65c83f99 100644 --- a/components/ChainSelector.tsx +++ b/components/ChainSelector.tsx @@ -44,14 +44,16 @@ const ChainSelector = () => { (option: OnChangeValue) => { setForkValue(option) onForkChange(option.value) - setSetting(Setting.VmFork, option) + setSetting(Setting.VmFork, option.value) }, [onForkChange, setSetting], ) useEffect(() => { - if (defaultForkOption) { - handleForkChange(getSetting(Setting.VmFork) || defaultForkOption) + if (settingsLoaded && defaultForkOption) { + const setting = getSetting(Setting.VmFork) + const storedFork = forkOptions.find((fork) => fork.value === setting) + handleForkChange(storedFork || defaultForkOption) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [settingsLoaded, defaultForkOption]) diff --git a/components/Editor/index.tsx b/components/Editor/index.tsx index 29fea0af..f8c198d9 100644 --- a/components/Editor/index.tsx +++ b/components/Editor/index.tsx @@ -105,7 +105,9 @@ const Editor = ({ readOnly = false }: Props) => { log('Solidity compiler loaded') return () => { - if (solcWorkerRef?.current) solcWorkerRef.current.terminate() + if (solcWorkerRef?.current) { + solcWorkerRef.current.terminate() + } } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) @@ -130,7 +132,9 @@ const Editor = ({ readOnly = false }: Props) => { } const highlightCode = (value: string) => { - if (!codeType) return value + if (!codeType) { + return value + } return codeHighlight(value, codeType) .value.split('\n') diff --git a/components/Reference/DocRow.tsx b/components/Reference/DocRow.tsx index 42d1d9f4..d165a779 100644 --- a/components/Reference/DocRow.tsx +++ b/components/Reference/DocRow.tsx @@ -1,12 +1,23 @@ +import { useContext, useMemo, useEffect, useState } from 'react' + +import cn from 'classnames' import { MDXRemote } from 'next-mdx-remote' -import { IOpcodeDoc } from 'types' +import { IOpcode, IOpcodeDoc, IOpcodeGasDoc } from 'types' + +import { EthereumContext } from 'context/ethereumContext' import { GITHUB_REPO_URL } from 'util/constants' +import { parseGasPrices, findMatchingForkName } from 'util/gas' import * as Doc from 'components/ui/Doc' +import DynamicFee from './DynamicFee' + type Props = { - opcode: IOpcodeDoc + opcodeDoc: IOpcodeDoc + opcode: IOpcode + gasDocs: IOpcodeGasDoc + dynamicFeeForkName: string } const docComponents = { @@ -21,32 +32,87 @@ const docComponents = { th: Doc.TH, td: Doc.TD, a: Doc.A, + pre: Doc.Pre, } -const DocRow = ({ opcode }: Props) => { +const API_DYNAMIC_FEE_DOC_URL = '/api/getDynamicDoc' + +const DocRow = ({ opcodeDoc, opcode, gasDocs, dynamicFeeForkName }: Props) => { + const { common, forks, selectedFork } = useContext(EthereumContext) + const [dynamicFeeDocMdx, setDynamicFeeDocMdx] = useState() + + const dynamicFeeDoc = useMemo(() => { + if (!gasDocs) { + return null + } + const fork = findMatchingForkName(forks, Object.keys(gasDocs), selectedFork) + return fork && common ? parseGasPrices(common, gasDocs[fork]) : null + }, [forks, selectedFork, gasDocs, common]) + + useEffect(() => { + let controller: AbortController | null = new AbortController() + + const fetchDynamicFeeDoc = async () => { + try { + const response = await fetch(API_DYNAMIC_FEE_DOC_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ content: dynamicFeeDoc }), + signal: controller?.signal, + }) + const data = await response.json() + setDynamicFeeDocMdx(data.mdx) + controller = null + } catch (error) { + setDynamicFeeDocMdx(undefined) + } + } + + if (dynamicFeeDoc) { + fetchDynamicFeeDoc() + } + + return () => controller?.abort() + }, [dynamicFeeDoc]) + return (
- {opcode && ( + {opcodeDoc && ( <> - - + + - - + +
SinceGroupSinceGroup
{opcode.meta.fork}{opcode.meta.group}{opcodeDoc.meta.fork}{opcodeDoc.meta.group}
- +
+
+ + {dynamicFeeForkName && dynamicFeeDocMdx && ( + + )} +
+ + {dynamicFeeForkName && ( + + )} +
)} - {!opcode && ( + {!opcodeDoc && (
There is no reference doc for this opcode yet. Why not{' '} { + const { dynamicFee } = opcode + const forkInputs = dynamicFee ? dynamicFee[fork].inputs : null + + const { common } = useContext(EthereumContext) + const [inputs, setInputs] = useState() + const [result, setResult] = useState('0') + + const handleCompute = debounce((inputs) => { + if (common) { + try { + setResult(calculateDynamicFee(opcode, common, inputs)) + } catch (error) { + console.error(error) + } + } + }, debounceTimeout) + + // Initialize inputs with default keys & values + useEffect(() => { + const inputValues: InputValue = {} + Object.keys(forkInputs || []).map((key: string) => { + inputValues[key] = '0' // false for boolean, zero for numbers + }) + setInputs(inputValues) + handleCompute(inputValues) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dynamicFee]) + + const handleChange = (key: string, value: string) => { + const newInputs = { + ...inputs, + [key]: value, + } + setInputs(newInputs) + handleCompute(newInputs) + } + + if (!forkInputs || !inputs) { + return null + } + + return ( +
+
+

Estimate your gas cost

+
+ +
+ {Object.keys(forkInputs).map((key: string) => { + const input = forkInputs[key] + + return ( +
+ + + {input.type === 'number' && ( + handleChange(key, e.target.value)} + className="bg-white bg-opacity-75 dark:bg-black-400 mb-4 text-sm font-mono" + /> + )} + + {input.type === 'boolean' && ( +
+ handleChange(key, '1')} + /> + handleChange(key, '0')} + /> +
+ )} +
+ ) + })} + +
+ + Static gas + dynamic gas = {result} +
+
+
+ ) +} + +export default DynamicFee diff --git a/components/Reference/Filters.tsx b/components/Reference/Filters.tsx index f6510344..64f9d613 100644 --- a/components/Reference/Filters.tsx +++ b/components/Reference/Filters.tsx @@ -62,6 +62,7 @@ const Filters = ({ onSetFilter }: Props) => { handleKeywordChange(e.target.value) }} placeholder={`Enter keyword...`} + className="bg-gray-100 dark:bg-black-500" />
) diff --git a/components/Reference/data.tsx b/components/Reference/data.tsx index a89b3a42..2790373f 100644 --- a/components/Reference/data.tsx +++ b/components/Reference/data.tsx @@ -22,8 +22,8 @@ const tableData = [ width: 128, }, { - Header: 'Static Gas', - accessor: 'fee', + Header: 'Minimum Gas', + accessor: 'minimumFee', width: 96, }, { diff --git a/components/Reference/index.tsx b/components/Reference/index.tsx index 15e4e494..f9f8c7f9 100644 --- a/components/Reference/index.tsx +++ b/components/Reference/index.tsx @@ -12,10 +12,12 @@ import useWindowSize from 'lib/useWindowResize' import { useRouter } from 'next/router' import { useTable, useExpanded, useFilters, HeaderGroup } from 'react-table' import ReactTooltip from 'react-tooltip' -import { IOpcode, IOpcodeDocs } from 'types' +import { IOpcode, IOpcodeDocs, IOpcodeGasDocs } from 'types' import { EthereumContext } from 'context/ethereumContext' +import { findMatchingForkName } from 'util/gas' + import { Button, Icon } from 'components/ui' import tableData from './data' @@ -27,19 +29,15 @@ type CustomHeaderGroup = { className?: string } & HeaderGroup -// FIXME: Remove once https://github.com/comitylabs/evm.codes/issues/57 is done -const DynamicFeeTooltip = () => ( - - - -) - -const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { +const ReferenceTable = ({ + opcodeDocs, + gasDocs, +}: { + opcodeDocs: IOpcodeDocs + gasDocs: IOpcodeGasDocs +}) => { const router = useRouter() - const { opcodes } = useContext(EthereumContext) + const { opcodes, forks, selectedFork } = useContext(EthereumContext) const data = useMemo(() => opcodes, [opcodes]) const columns = useMemo(() => tableData, []) const rowRefs = useRef([]) @@ -110,7 +108,9 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { ) } - if (opcodes.length === 0) return null + if (opcodes.length === 0) { + return null + } return ( <> @@ -171,11 +171,14 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { prepareRow(row) const { code } = row.values + const rowId = parseInt(row.id) // @ts-ignore: Waiting for 8.x of react-table to have better types - const isExpanded = row.isExpanded || focusedOpcode === row.id - const hasDynamicFee = opcodes.find( - (opcode) => opcode.code == code, - )?.dynamicFee + const isExpanded = row.isExpanded || focusedOpcode === rowId + const dynamicFeeForkName = findMatchingForkName( + forks, + Object.keys(opcodes[rowId]?.dynamicFee || {}), + selectedFork, + ) return ( @@ -187,7 +190,9 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { isExpanded, })} ref={(el) => { - if (el) rowRefs.current[row.index] = el + if (el) { + rowRefs.current[row.index] = el + } }} // @ts-ignore: Waiting for 8.x of react-table to have better types onClick={() => row.toggleRowExpanded()} @@ -205,9 +210,21 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { >
{cell.render('Cell')} - {cell.column.id === 'fee' && hasDynamicFee && ( - - )} + {cell.column.id === 'minimumFee' && + !!dynamicFeeForkName && ( + + + + + )}
))} @@ -216,7 +233,12 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { {isExpanded ? ( - + ) : null} @@ -225,8 +247,6 @@ const ReferenceTable = ({ opcodeDocs }: { opcodeDocs: IOpcodeDocs }) => { })} - - ) } diff --git a/components/layouts/Home.tsx b/components/layouts/Home.tsx index c7cdd273..eca03519 100644 --- a/components/layouts/Home.tsx +++ b/components/layouts/Home.tsx @@ -1,6 +1,5 @@ import type { NextPage } from 'next' import Head from 'next/head' -import Script from 'next/script' import { getAbsoluteURL } from 'util/browser' @@ -29,8 +28,6 @@ const HomeLayout: NextPage = ({ children }) => { -