1import React, { useCallback, useEffect, useState } from 'react';
2import { Box, Row, Icon, StatelessTextInput } from '@tlon/indigo-react';
3import { DEFAULT_GAS_PRICE_GWEI } from 'lib/constants';
4import useGasPrice from 'lib/useGasPrice';
6import Dropdown from './Dropdown';
7import './FeeDropdown.scss';
8import { defaultGasValues } from 'lib/getSuggestedGasPrice';
10const PRICE_LABELS = ['Fast', 'Normal', 'Slow'];
12export interface GasPriceData {
15 maxFeePerGas: string; // hex
16 maxPriorityFeePerGas: number;
17 suggestedBaseFeePerGas: number;
20export const formatDisplay = ({ price, wait }: GasPriceData) =>
21 `${price} gwei (${wait} min)`;
23export default function FeeDropdown({
26 setGasPrice: (g: GasPriceData) => void;
28 const { suggestedGasPrices }: { suggestedGasPrices: {
30 average: GasPriceData,
32 }} = useGasPrice(DEFAULT_GAS_PRICE_GWEI);
34 const [open, setOpen] = useState(false);
35 const [useCustom, setUseCustom] = useState(false);
36 const [custom, setCustom] = useState<string | undefined>();
37 const [selected, setSelected] = useState<GasPriceData>(
38 suggestedGasPrices.average
41 const handleCustom = (e: React.ChangeEvent<HTMLInputElement>) => {
42 const cleanedValue = e.target.value.replace(/[^0-9]/g, '');
43 const cleanedNum = Number(cleanedValue);
44 setCustom(cleanedValue);
45 setGasPrice(defaultGasValues(cleanedNum).average);
47 let customWait = 'Unknown';
49 const { fast, average, low } = suggestedGasPrices;
51 if (cleanedNum < low.price) {
52 customWait = `> ${low.wait}`;
53 } else if (cleanedNum < average.price) {
54 customWait = `~${low.wait}`;
55 } else if (cleanedNum < fast.price) {
56 customWait = `~${average.wait}`;
58 customWait = `< ${fast.wait}`;
64 maxFeePerGas: cleanedNum,
65 maxPriorityFeePerGas: cleanedNum,
66 suggestedBaseFeePerGas: cleanedNum
71 setSelected(suggestedGasPrices.average);
72 }, [suggestedGasPrices]);
74 const selectPrice = useCallback(
75 (value: GasPriceData) => () => {
80 [setGasPrice, setSelected, setOpen]
85 <Row className="fee-dropdown custom">
88 className="custom-input"
89 placeholder="Custom gwei"
90 onChange={handleCustom}
107 className="fee-dropdown"
109 value={formatDisplay(selected)}
110 toggleOpen={() => setOpen(!open)}>
111 <Box className="prices">
112 {Object.values(suggestedGasPrices).map(
113 (value: GasPriceData, ind: number) => (
116 onClick={selectPrice(value)}
117 key={`gas-price-${ind}`}>
118 <Box className="speed">{PRICE_LABELS[ind]}</Box>
119 <Box className="time">{formatDisplay(value)}</Box>
123 <Row className="price" onClick={() => setUseCustom(true)}>
124 <Box className="time">Custom...</Box>
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list