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;
33 average: GasPriceData;
36 } = useGasPrice(DEFAULT_GAS_PRICE_GWEI);
38 const [open, setOpen] = useState(false);
39 const [useCustom, setUseCustom] = useState(false);
40 const [custom, setCustom] = useState<string | undefined>();
41 const [selected, setSelected] = useState<GasPriceData>(
42 suggestedGasPrices.average
45 const handleCustom = (e: React.ChangeEvent<HTMLInputElement>) => {
46 // Allow digits and a single decimal point
47 const cleanedValue = e.target.value
48 .replace(/[^0-9.]/g, '')
49 .replace(/(\..*)\./g, '$1');
50 const cleanedNum = Number(cleanedValue);
51 setCustom(cleanedValue);
52 setGasPrice(defaultGasValues(cleanedNum).average);
54 let customWait = 'Unknown';
56 const { fast, average, low } = suggestedGasPrices;
58 if (cleanedNum < low.price) {
59 customWait = `> ${low.wait}`;
60 } else if (cleanedNum < average.price) {
61 customWait = `~${low.wait}`;
62 } else if (cleanedNum < fast.price) {
63 customWait = `~${average.wait}`;
65 customWait = `< ${fast.wait}`;
71 maxFeePerGas: cleanedNum,
72 maxPriorityFeePerGas: cleanedNum,
73 suggestedBaseFeePerGas: cleanedNum,
78 setSelected(suggestedGasPrices.average);
79 }, [suggestedGasPrices]);
81 const selectPrice = useCallback(
82 (value: GasPriceData) => () => {
87 [setGasPrice, setSelected, setOpen]
92 <Row className="fee-dropdown custom">
95 className="custom-input"
96 placeholder="Custom gwei"
97 onChange={handleCustom}
114 className="fee-dropdown"
116 value={formatDisplay(selected)}
117 toggleOpen={() => setOpen(!open)}>
118 <Box className="prices">
119 {Object.values(suggestedGasPrices).map(
120 (value: GasPriceData, ind: number) => (
123 onClick={selectPrice(value)}
124 key={`gas-price-${ind}`}>
125 <Box className="speed">{PRICE_LABELS[ind]}</Box>
126 <Box className="time">{formatDisplay(value)}</Box>
130 <Row className="price" onClick={() => setUseCustom(true)}>
131 <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