Skip to content

Commit

Permalink
feat: add gas adjustment
Browse files Browse the repository at this point in the history
  • Loading branch information
jinoosss committed Jan 16, 2025
1 parent 1c51140 commit 04fc348
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 49 deletions.
9 changes: 9 additions & 0 deletions packages/adena-extension/src/common/constants/gas.constant.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { NetworkFeeSettingType } from '@types';

// Gnoland default gas price (1ugnot/1000gas)
// https://github.com/gnolang/gno/blob/master/gno.land/pkg/gnoland/genesis.go#L20
export const MINIMUM_GAS_PRICE = 0.001 as const;

// Adena default gas used
// When the gas used is not set, the default value is 100,000
export const DEFAULT_GAS_USED = 100_000 as const;

// Default gas price step
// Slow = 0.001, Average = 0.0025, Fast = 0.004
export const DEFAULT_GAS_PRICE_STEP: Record<NetworkFeeSettingType, number> = {
FAST: 0.004,
AVERAGE: 0.0025,
SLOW: 0.001,
} as const;

// Default gas adjustment
export const DEFAULT_GAS_ADJUSTMENT = 1.6 as const;

// Gas fee safety margin
// This is gas wanted safety margin
export const GAS_FEE_SAFETY_MARGIN = 1.2 as const;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GasToken } from '@common/constants/token.constant';
import { NetworkFeeSettingInfo, NetworkFeeSettingType } from '@types';
import { GasInfo, NetworkFeeSettingType } from '@types';
import BigNumber from 'bignumber.js';
import React, { useMemo } from 'react';
import { TokenBalance } from '../token-balance';
Expand All @@ -12,7 +12,10 @@ export interface NetworkFeeSettingItemProps {
selected: boolean;
isLoading: boolean;
select: () => void;
info: NetworkFeeSettingInfo;
info: {
settingType: NetworkFeeSettingType;
gasInfo?: GasInfo | undefined;
};
}

const networkFeeSettingTypeNames: { [key in NetworkFeeSettingType]: string } = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { SubHeader } from '@components/atoms';
import { GasInfo, NetworkFeeSettingInfo, NetworkFeeSettingType } from '@types';

import { BottomFixedButton } from '@components/molecules';
import NetworkFeeCustomInput from '@components/molecules/network-fee-custom-input/network-fee-custom-input';
import NetworkFeeSettingItem from '@components/molecules/network-fee-setting-item/network-fee-setting-item';
import BigNumber from 'bignumber.js';
import { NetworkFeeSettingWrapper } from './network-fee-setting.styles';
Expand All @@ -16,7 +17,7 @@ export interface NetworkFeeSettingProps {
setNetworkFeeSetting: (settingInfo: NetworkFeeSettingInfo) => void;
gasAdjustment: string;
setGasAdjustment: (ratio: string) => void;
networkFeeSettings: NetworkFeeSettingInfo[];
networkFeeSettings: NetworkFeeSettingInfo[] | null;
onClickBack: () => void;
onClickSave: () => void;
}
Expand All @@ -33,16 +34,26 @@ const NetworkFeeSetting: React.FC<NetworkFeeSettingProps> = ({
networkFeeSettingType,
setNetworkFeeSetting,
networkFeeSettings,
gasAdjustment,
setGasAdjustment,
onClickBack,
onClickSave,
}) => {
const settingInfoMap = useMemo(() => {
if (!networkFeeSettings) {
return {
[NetworkFeeSettingType.FAST]: null,
[NetworkFeeSettingType.AVERAGE]: null,
[NetworkFeeSettingType.SLOW]: null,
};
}

return networkFeeSettings.reduce(
(acc, setting) => {
acc[setting.settingType] = setting;
return acc;
},
{} as Record<NetworkFeeSettingType, NetworkFeeSettingInfo>,
{} as Record<NetworkFeeSettingType, NetworkFeeSettingInfo | null>,
);
}, [networkFeeSettings]);

Expand All @@ -62,12 +73,25 @@ const NetworkFeeSetting: React.FC<NetworkFeeSettingProps> = ({
}, [changedGasInfo]);

const isSelected = useCallback(
(settingInfo: NetworkFeeSettingInfo) => {
return settingInfo.settingType === networkFeeSettingType;
(settingInfo: { settingType: NetworkFeeSettingType; gasInfo?: GasInfo | undefined }) => {
return settingInfo?.settingType === networkFeeSettingType;
},
[networkFeeSettingType],
);

const onChangeGasAdjustment = useCallback((value: string) => {
if (BigNumber(value).isNaN()) {
return;
}

// 3 is the maximum value of gas adjustment
if (BigNumber(value).isGreaterThan(3)) {
return;
}

setGasAdjustment(value);
}, []);

return (
<NetworkFeeSettingWrapper>
<SubHeader
Expand All @@ -86,16 +110,26 @@ const NetworkFeeSetting: React.FC<NetworkFeeSettingProps> = ({
selected={isSelected(settingInfo)}
isLoading={!isFetchedPriceTiers}
info={settingInfo}
select={(): void => setNetworkFeeSetting(settingInfo)}
select={(): void =>
setNetworkFeeSetting({
settingType: settingInfo.settingType,
gasInfo: {
...(settingInfo.gasInfo || {
gasFee: 0,
gasPrice: 0,
gasUsed: 0,
gasWanted: 0,
}),
},
})
}
/>
))}
</div>

{/* We need more information about the gas estimation.
<div className='custom-network-fee-input-wrapper'>
<NetworkFeeCustomInput value={gasAdjustment} onChange={onChangeCustomFee} />
</div>
*/}
<NetworkFeeCustomInput value={gasAdjustment} onChange={onChangeGasAdjustment} />
</div>
</div>

<BottomFixedButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,25 @@ function modifyDocument(document: Document, gasWanted: number, gasFee: number):
};
}

export const defaultGasPriceTiers: NetworkFeeSettingInfo[] = Object.keys(
DEFAULT_GAS_PRICE_STEP,
).map((key) => {
const tier = key as NetworkFeeSettingType;
const gasPrice = DEFAULT_GAS_PRICE_STEP[tier];

return {
settingType: tier,
gasInfo: {
gasFee: 0,
gasUsed: 0,
gasWanted: 0,
gasPrice: gasPrice,
},
};
});

export const useGetEstimateGasPriceTiers = (
document: Document | null | undefined,
gasUsed: number,
gasAdjustment: string,
options?: UseQueryOptions<NetworkFeeSettingInfo[], Error>,
): UseQueryResult<NetworkFeeSettingInfo[]> => {
options?: UseQueryOptions<NetworkFeeSettingInfo[] | null, Error>,
): UseQueryResult<NetworkFeeSettingInfo[] | null> => {
const { transactionGasService } = useAdenaContext();

return useQuery<NetworkFeeSettingInfo[], Error>({
return useQuery<NetworkFeeSettingInfo[] | null, Error>({
queryKey: [
GET_ESTIMATE_GAS_PRICE_TIERS,
document?.msgs,
document?.memo,
gasUsed,
gasAdjustment,
],
queryFn: async (): Promise<NetworkFeeSettingInfo[]> => {
queryFn: async (): Promise<NetworkFeeSettingInfo[] | null> => {
if (!document || !gasUsed) {
return defaultGasPriceTiers;
return null;
}

return Promise.all(
Expand All @@ -109,7 +92,6 @@ export const useGetEstimateGasPriceTiers = (
const result = await transactionGasService
.estimateGas(documentToDefaultTx(modifiedDocument))
.catch((e: Error) => {
console.log('e', e);
if (e.message === '/std.InvalidPubKeyError') {
return DEFAULT_GAS_USED;
}
Expand Down
22 changes: 16 additions & 6 deletions packages/adena-extension/src/hooks/wallet/use-network-fee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import {
useGetDefaultEstimateGasInfo,
useGetEstimateGasInfo,
} from './transaction-gas/use-get-estimate-gas-info';
import {
defaultGasPriceTiers,
useGetEstimateGasPriceTiers,
} from './transaction-gas/use-get-estimate-gas-price-tiers';
import { useGetEstimateGasPriceTiers } from './transaction-gas/use-get-estimate-gas-price-tiers';

export interface UseNetworkFeeReturn {
isFetchedPriceTiers: boolean;
Expand All @@ -20,7 +17,7 @@ export interface UseNetworkFeeReturn {
changedGasInfo: GasInfo | null;
networkFee: NetworkFee | null;
networkFeeSettingType: NetworkFeeSettingType;
networkFeeSettings: NetworkFeeSettingInfo[];
networkFeeSettings: NetworkFeeSettingInfo[] | null;
gasAdjustment: string;
setGasAdjustment: (ratio: string) => void;
setNetworkFeeSetting: (settingInfo: NetworkFeeSettingInfo) => void;
Expand All @@ -37,6 +34,7 @@ export const useNetworkFee = (
useState<NetworkFeeSettingType>(defaultSettingType);
const [networkFeeSettingType, setNetworkFeeSettingType] =
useState<NetworkFeeSettingType>(defaultSettingType);

const [selectedTier, setSelectedTier] = useState(!isDefaultGasPrice);
const [gasAdjustment, setGasAdjustment] = useState<string>(DEFAULT_GAS_ADJUSTMENT.toString());

Expand All @@ -46,7 +44,7 @@ export const useNetworkFee = (
defaultEstimatedGasInfo?.gasUsed || 0,
defaultEstimatedGasInfo?.gasPrice || 0,
);
const { data: gasPriceTiers = defaultGasPriceTiers, isFetched: isFetchedPriceTiers } =
const { data: gasPriceTiers = null, isFetched: isFetchedPriceTiers } =
useGetEstimateGasPriceTiers(document, estimatedGasInfo?.gasUsed || 0, gasAdjustment);

const currentSettingType = useMemo(() => {
Expand All @@ -66,12 +64,20 @@ export const useNetworkFee = (
}, [networkFeeSettingType, gasPriceTiers]);

const currentGasInfo = useMemo(() => {
if (!gasPriceTiers) {
return null;
}

const current = gasPriceTiers.find((setting) => setting.settingType === currentSettingType);

return current?.gasInfo || null;
}, [currentSettingType, gasPriceTiers]);

const changedGasInfo = useMemo(() => {
if (!gasPriceTiers) {
return null;
}

const current = gasPriceTiers.find((setting) => setting.settingType === changedSettingType);

return current?.gasInfo || null;
Expand All @@ -92,6 +98,10 @@ export const useNetworkFee = (
}, [currentGasInfo, document, selectedTier]);

const currentEstimateGas = useMemo(() => {
if (!gasPriceTiers) {
return null;
}

const current = gasPriceTiers.find((setting) => setting.settingType === currentSettingType);

return current?.gasInfo || null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const NFTTransferSummaryContainer: React.FC = () => {
.isGreaterThanOrEqualTo(networkFee.amount);
}, [gnoProvider, currentAddress, summaryInfo, networkFee]);

const transfer = useCallback(async () => {
const transfer = async (): Promise<boolean> => {
if (isSent || !currentAccount) {
return false;
}
Expand All @@ -128,7 +128,7 @@ const NFTTransferSummaryContainer: React.FC = () => {
return transferByLedger();
}
return transferByCommon();
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
};

const transferByCommon = useCallback(async () => {
try {
Expand All @@ -141,15 +141,15 @@ const NFTTransferSummaryContainer: React.FC = () => {
}
setIsSent(false);
return false;
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
}, [createTransaction]);

const transferByLedger = useCallback(async () => {
const document = await createDocument();
if (document) {
navigate(RoutePath.TransferLedgerLoading, { state: { document } });
}
return true;
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
}, [createDocument]);

const onClickBack = useCallback(() => {
if (memorizedTransferInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,16 @@ const TransferSummaryContainer: React.FC = () => {
console.error(e);
return null;
});
}, [summaryInfo, currentAccount, currentNetwork, networkFee]);
}, [
summaryInfo,
currentAccount,
currentNetwork,
networkFee,
useNetworkFeeReturn.currentGasFeeRawAmount,
useNetworkFeeReturn.currentGasInfo,
]);

const transfer = useCallback(async () => {
const transfer = async (): Promise<boolean> => {
if (isSent || !currentAccount) {
return false;
}
Expand All @@ -201,7 +208,7 @@ const TransferSummaryContainer: React.FC = () => {
return transferByLedger();
}
return transferByCommon();
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
};

const transferByCommon = useCallback(async () => {
try {
Expand All @@ -214,15 +221,15 @@ const TransferSummaryContainer: React.FC = () => {
}
setIsSent(false);
return false;
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
}, [createTransaction]);

const transferByLedger = useCallback(async () => {
const document = await createDocument();
if (document) {
navigate(RoutePath.TransferLedgerLoading, { state: { document } });
}
return true;
}, [summaryInfo, currentAccount, isSent, hasNetworkFee]);
}, [createDocument]);

const onClickBack = useCallback(() => {
setMemorizedTransferInfo(summaryInfo);
Expand Down

0 comments on commit 04fc348

Please sign in to comment.