Skip to content

Commit 17bb288

Browse files
committed
fix: calculate gas fee
1 parent 96ea02e commit 17bb288

File tree

3 files changed

+136
-113
lines changed

3 files changed

+136
-113
lines changed

packages/adena-extension/src/hooks/wallet/transaction-gas/use-get-estimate-gas-info.ts

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { DEFAULT_GAS_USED } from '@common/constants/gas.constant';
22
import { GasToken } from '@common/constants/token.constant';
3-
import { DEFAULT_GAS_WANTED } from '@common/constants/tx.constant';
4-
import { useAdenaContext } from '@hooks/use-context';
3+
import { Tx } from '@gnolang/tm2-js-client';
4+
import { useAdenaContext, useWalletContext } from '@hooks/use-context';
5+
import { TransactionService } from '@services/index';
56
import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
67
import { GasInfo } from '@types';
7-
import { Document, documentToDefaultTx } from 'adena-module';
8+
import { Document, documentToDefaultTx, Wallet } from 'adena-module';
89
import BigNumber from 'bignumber.js';
910
import { useGetGasPrice } from './use-get-gas-price';
1011

@@ -29,7 +30,7 @@ function makeGasInfoBy(
2930
const gasFeeBN = BigNumber(gasUsed).multipliedBy(gasPrice);
3031

3132
return {
32-
gasWanted: DEFAULT_GAS_WANTED,
33+
gasWanted: Number(gasUsed),
3334
gasFee: Number(gasFeeBN.toFixed(0, BigNumber.ROUND_UP)),
3435
};
3536
}
@@ -57,13 +58,59 @@ export const useGetDefaultEstimateGasInfo = (
5758
return useGetEstimateGasInfo(document, DEFAULT_GAS_USED, options);
5859
};
5960

61+
export const makeEstimateGasTransaction = async (
62+
wallet: Wallet | null,
63+
transactionService: TransactionService | null,
64+
document: Document | null | undefined,
65+
gasUsed: number,
66+
gasPrice: number | null,
67+
): Promise<Tx | null> => {
68+
if (!document || !gasPrice) {
69+
return null;
70+
}
71+
72+
const { gasFee, gasWanted } = makeGasInfoBy(gasUsed, gasPrice);
73+
if (!transactionService || !gasFee || !gasWanted || !wallet) {
74+
return null;
75+
}
76+
77+
const modifiedDocument = modifyDocument(document, gasWanted, gasFee);
78+
79+
// current tx size not calculate
80+
// if (isInitializedAccount) {
81+
// return documentToDefaultTx(modifiedDocument);
82+
// }
83+
84+
const { signed } = await transactionService
85+
.createTransaction(wallet, modifiedDocument)
86+
.catch(() => {
87+
return {
88+
signed: null,
89+
};
90+
});
91+
if (!signed) {
92+
return documentToDefaultTx(modifiedDocument);
93+
}
94+
95+
return signed;
96+
};
97+
6098
export const useGetEstimateGasInfo = (
6199
document: Document | null | undefined,
62100
gasUsed: number,
63101
options?: UseQueryOptions<GasInfo | null, Error>,
64102
): UseQueryResult<GasInfo | null> => {
65103
const { data: gasPrice } = useGetGasPrice();
66-
const { transactionGasService } = useAdenaContext();
104+
const { wallet } = useWalletContext();
105+
const { transactionService, transactionGasService } = useAdenaContext();
106+
107+
async function makeTransaction(document: Document | null | undefined): Promise<Tx | null> {
108+
if (!document || !gasPrice) {
109+
return null;
110+
}
111+
112+
return makeEstimateGasTransaction(wallet, transactionService, document, gasUsed, gasPrice);
113+
}
67114

68115
return useQuery<GasInfo | null, Error>({
69116
queryKey: [
@@ -74,20 +121,18 @@ export const useGetEstimateGasInfo = (
74121
gasUsed,
75122
gasPrice || 0,
76123
],
77-
queryFn: async () => {
78-
if (!document || !gasPrice) {
124+
queryFn: async (): Promise<GasInfo | null> => {
125+
if (!transactionGasService || !gasPrice) {
79126
return null;
80127
}
81128

82-
const { gasFee, gasWanted } = makeGasInfoBy(gasUsed, gasPrice);
83-
if (!transactionGasService || !gasFee || !gasWanted) {
129+
const tx = await makeTransaction(document);
130+
if (!tx) {
84131
return null;
85132
}
86133

87-
const modifiedDocument = modifyDocument(document, gasWanted, gasFee);
88-
89-
const result = await transactionGasService
90-
.estimateGas(documentToDefaultTx(modifiedDocument))
134+
const resultGasUsed = await transactionGasService
135+
.estimateGas(tx)
91136
.then((gasUsed) => ({
92137
gasUsed,
93138
errorMessage: null,
@@ -103,24 +148,28 @@ export const useGetEstimateGasInfo = (
103148
return null;
104149
});
105150

106-
if (!result) {
151+
if (!resultGasUsed) {
107152
return {
108-
gasFee,
109-
gasUsed,
110-
gasWanted,
153+
gasFee: 0,
154+
gasUsed: 0,
155+
gasWanted: 0,
111156
gasPrice: 0,
112157
hasError: true,
113158
simulateErrorMessage: '',
114159
};
115160
}
116161

162+
const gasFee = BigNumber(resultGasUsed.gasUsed)
163+
.multipliedBy(gasPrice)
164+
.toFixed(0, BigNumber.ROUND_UP);
165+
117166
return {
118-
gasFee: gasFee,
119-
gasUsed: result.gasUsed,
120-
gasWanted: gasWanted,
167+
gasFee: Number(gasFee),
168+
gasUsed: resultGasUsed.gasUsed,
169+
gasWanted: resultGasUsed.gasUsed,
121170
gasPrice: gasPrice,
122-
hasError: result.errorMessage !== null,
123-
simulateErrorMessage: result.errorMessage,
171+
hasError: resultGasUsed.errorMessage !== null,
172+
simulateErrorMessage: resultGasUsed.errorMessage,
124173
};
125174
},
126175
refetchInterval: REFETCH_INTERVAL,

packages/adena-extension/src/hooks/wallet/transaction-gas/use-get-estimate-gas-price-tiers.ts

Lines changed: 65 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,26 @@
1-
import { DEFAULT_GAS_PRICE_RATE, GAS_FEE_SAFETY_MARGIN } from '@common/constants/gas.constant';
2-
import { GasToken } from '@common/constants/token.constant';
1+
import { DEFAULT_GAS_PRICE_RATE, DEFAULT_GAS_USED } from '@common/constants/gas.constant';
32
import { INVALID_PUBLIC_KEY_ERROR_TYPE } from '@common/constants/tx-error.constant';
4-
import { DEFAULT_GAS_WANTED } from '@common/constants/tx.constant';
5-
import { useAdenaContext } from '@hooks/use-context';
3+
import { useAdenaContext, useWalletContext } from '@hooks/use-context';
64
import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
75
import { NetworkFeeSettingInfo, NetworkFeeSettingType } from '@types';
8-
import { Document, documentToDefaultTx } from 'adena-module';
6+
import { Document } from 'adena-module';
97
import BigNumber from 'bignumber.js';
8+
import { makeEstimateGasTransaction } from './use-get-estimate-gas-info';
109
import { useGetGasPrice } from './use-get-gas-price';
1110

1211
export const GET_ESTIMATE_GAS_PRICE_TIERS = 'transactionGas/getEstimateGasPriceTiers';
1312

1413
const REFETCH_INTERVAL = 5_000;
1514

16-
function makeGasInfoBy(
17-
gasUsed: number | null | undefined,
18-
gasPrice: number | null | undefined,
19-
safetyMargin: number,
20-
): {
21-
gasWanted: number;
22-
gasFee: number;
23-
} {
24-
if (!gasUsed || !gasPrice) {
25-
return {
26-
gasWanted: 0,
27-
gasFee: 0,
28-
};
29-
}
30-
31-
const gasWantedBN = BigNumber(gasUsed).multipliedBy(safetyMargin);
32-
const gasFeeBN = BigNumber(gasUsed).multipliedBy(gasPrice);
33-
34-
return {
35-
gasWanted: Number(gasWantedBN.toFixed(0, BigNumber.ROUND_DOWN)),
36-
gasFee: Number(gasFeeBN.toFixed(0, BigNumber.ROUND_UP)),
37-
};
38-
}
39-
40-
function makeDefaultGasInfoBy(
41-
gasUsed: number | null | undefined,
42-
gasPrice: number | null | undefined,
43-
): {
44-
gasWanted: number;
45-
gasFee: number;
46-
} {
47-
if (!gasUsed || !gasPrice) {
48-
return {
49-
gasWanted: 0,
50-
gasFee: 0,
51-
};
52-
}
53-
54-
const gasFeeBN = BigNumber(gasUsed).multipliedBy(gasPrice);
55-
56-
return {
57-
gasWanted: DEFAULT_GAS_WANTED,
58-
gasFee: Number(gasFeeBN.toFixed(0, BigNumber.ROUND_UP)),
59-
};
60-
}
61-
62-
function modifyDocument(document: Document, gasWanted: number, gasFee: number): Document {
63-
return {
64-
...document,
65-
fee: {
66-
...document.fee,
67-
gas: gasWanted.toString(),
68-
amount: [
69-
{
70-
denom: GasToken.denom,
71-
amount: gasFee.toString(),
72-
},
73-
],
74-
},
75-
};
76-
}
77-
7815
export const useGetEstimateGasPriceTiers = (
7916
document: Document | null | undefined,
8017
gasUsed: number | undefined,
8118
gasAdjustment: string,
82-
isSuccessSimulate = true,
8319
options?: UseQueryOptions<NetworkFeeSettingInfo[] | null, Error>,
8420
): UseQueryResult<NetworkFeeSettingInfo[] | null> => {
85-
const { transactionGasService } = useAdenaContext();
21+
const { transactionGasService, transactionService } = useAdenaContext();
8622
const { data: gasPrice } = useGetGasPrice();
23+
const { wallet } = useWalletContext();
8724

8825
return useQuery<NetworkFeeSettingInfo[] | null, Error>({
8926
queryKey: [
@@ -96,45 +33,83 @@ export const useGetEstimateGasPriceTiers = (
9633
gasPrice || 0,
9734
],
9835
queryFn: async (): Promise<NetworkFeeSettingInfo[] | null> => {
99-
if (!transactionGasService || !document || gasUsed === undefined || !gasPrice) {
36+
if (!transactionService || !transactionGasService || !document || !gasPrice) {
10037
return null;
10138
}
10239

10340
return Promise.all(
10441
Object.keys(NetworkFeeSettingType).map(async (key) => {
10542
const tier = key as NetworkFeeSettingType;
10643

107-
const adjustedGasPriceBN = BigNumber(gasPrice)
108-
.multipliedBy(DEFAULT_GAS_PRICE_RATE[tier])
109-
.multipliedBy(gasAdjustment);
44+
const adjustGasUsedBN = BigNumber(gasUsed || DEFAULT_GAS_USED).multipliedBy(
45+
DEFAULT_GAS_PRICE_RATE[tier],
46+
);
47+
const adjustGasUsed = adjustGasUsedBN.toFixed(0, BigNumber.ROUND_DOWN);
48+
const adjustedGasPriceBN = BigNumber(gasPrice).multipliedBy(gasAdjustment);
11049
const adjustedGasPrice = adjustedGasPriceBN.toNumber();
111-
112-
const { gasWanted: resultGasWanted, gasFee: resultGasFee } = isSuccessSimulate
113-
? makeGasInfoBy(gasUsed, adjustedGasPrice, GAS_FEE_SAFETY_MARGIN)
114-
: makeDefaultGasInfoBy(gasUsed, adjustedGasPrice);
115-
116-
const modifiedDocument = modifyDocument(document, resultGasWanted, resultGasFee);
117-
118-
const errorMessage = await transactionGasService
119-
.simulateTx(documentToDefaultTx(modifiedDocument))
120-
.then(() => null)
50+
const gasFee = adjustedGasPriceBN
51+
.multipliedBy(adjustGasUsed)
52+
.toFixed(0, BigNumber.ROUND_UP);
53+
54+
const tx = await makeEstimateGasTransaction(
55+
wallet,
56+
transactionService,
57+
document,
58+
Number(adjustGasUsed),
59+
adjustedGasPriceBN.toNumber(),
60+
);
61+
62+
console.log('tx', tx);
63+
console.log('gasUsed', gasUsed);
64+
console.log('gasPrice', adjustedGasPrice);
65+
console.log('gasFee', gasFee);
66+
console.log('document', document);
67+
68+
if (!tx) {
69+
return {
70+
settingType: tier,
71+
gasInfo: {
72+
gasFee: 0,
73+
gasUsed: Number(adjustGasUsed),
74+
gasWanted: Number(adjustGasUsed),
75+
gasPrice: adjustedGasPrice,
76+
hasError: true,
77+
simulateErrorMessage: 'Failed to simulate transaction',
78+
},
79+
};
80+
}
81+
82+
const result = await transactionGasService
83+
.simulateTx(tx)
84+
.then((simulateResult) => {
85+
return {
86+
gasUsed: simulateResult.gasUsed.toNumber(),
87+
errorMessage: null,
88+
};
89+
})
12190
.catch((e: Error) => {
12291
if (e?.message === INVALID_PUBLIC_KEY_ERROR_TYPE) {
123-
return null;
92+
return {
93+
gasUsed: Number(adjustGasUsed),
94+
errorMessage: null,
95+
};
12496
}
12597

126-
return e?.message || '';
98+
return {
99+
gasUsed: Number(adjustGasUsed),
100+
errorMessage: e?.message || '',
101+
};
127102
});
128103

129104
return {
130105
settingType: tier,
131106
gasInfo: {
132-
gasFee: resultGasFee,
133-
gasUsed,
134-
gasWanted: resultGasWanted,
107+
gasFee: Number(gasFee),
108+
gasUsed: result.gasUsed,
109+
gasWanted: result.gasUsed,
135110
gasPrice: adjustedGasPrice,
136-
hasError: errorMessage !== null,
137-
simulateErrorMessage: errorMessage,
111+
hasError: result.errorMessage !== null,
112+
simulateErrorMessage: result.errorMessage,
138113
},
139114
};
140115
}),

packages/adena-extension/src/hooks/wallet/use-network-fee.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export const useNetworkFee = (
5353
document,
5454
gasInfo?.gasUsed || estimatedGasInfo?.gasUsed,
5555
gasAdjustment,
56-
!estimatedGasInfo?.hasError,
5756
);
5857

5958
const isLoading = useMemo(() => {

0 commit comments

Comments
 (0)