@keplr-wallet/hooks-evm 0.13.15-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +14 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +18 -0
- package/build/index.js.map +1 -0
- package/build/tx/amount.d.ts +27 -0
- package/build/tx/amount.js +238 -0
- package/build/tx/amount.js.map +1 -0
- package/build/tx/chain.d.ts +10 -0
- package/build/tx/chain.js +37 -0
- package/build/tx/chain.js.map +1 -0
- package/build/tx/errors.d.ts +30 -0
- package/build/tx/errors.js +84 -0
- package/build/tx/errors.js.map +1 -0
- package/build/tx/evm-fee-utils.d.ts +28 -0
- package/build/tx/evm-fee-utils.js +133 -0
- package/build/tx/evm-fee-utils.js.map +1 -0
- package/build/tx/fee.d.ts +61 -0
- package/build/tx/fee.js +523 -0
- package/build/tx/fee.js.map +1 -0
- package/build/tx/gas-simulator.d.ts +89 -0
- package/build/tx/gas-simulator.js +465 -0
- package/build/tx/gas-simulator.js.map +1 -0
- package/build/tx/gas.d.ts +12 -0
- package/build/tx/gas.js +84 -0
- package/build/tx/gas.js.map +1 -0
- package/build/tx/index.d.ts +13 -0
- package/build/tx/index.js +30 -0
- package/build/tx/index.js.map +1 -0
- package/build/tx/internal.d.ts +3 -0
- package/build/tx/internal.js +3 -0
- package/build/tx/internal.js.map +1 -0
- package/build/tx/name-service-ens.d.ts +40 -0
- package/build/tx/name-service-ens.js +189 -0
- package/build/tx/name-service-ens.js.map +1 -0
- package/build/tx/name-service.d.ts +20 -0
- package/build/tx/name-service.js +20 -0
- package/build/tx/name-service.js.map +1 -0
- package/build/tx/recipient.d.ts +35 -0
- package/build/tx/recipient.js +131 -0
- package/build/tx/recipient.js.map +1 -0
- package/build/tx/send-tx.d.ts +13 -0
- package/build/tx/send-tx.js +24 -0
- package/build/tx/send-tx.js.map +1 -0
- package/build/tx/sender.d.ts +12 -0
- package/build/tx/sender.js +73 -0
- package/build/tx/sender.js.map +1 -0
- package/build/tx/types.d.ts +102 -0
- package/build/tx/types.js +3 -0
- package/build/tx/types.js.map +1 -0
- package/build/tx/validate.d.ts +11 -0
- package/build/tx/validate.js +37 -0
- package/build/tx/validate.js.map +1 -0
- package/package.json +40 -0
- package/src/index.ts +1 -0
- package/src/tx/amount.ts +273 -0
- package/src/tx/chain.ts +31 -0
- package/src/tx/errors.ts +79 -0
- package/src/tx/evm-fee-utils.ts +217 -0
- package/src/tx/fee.ts +622 -0
- package/src/tx/gas-simulator.ts +567 -0
- package/src/tx/gas.ts +93 -0
- package/src/tx/index.ts +13 -0
- package/src/tx/internal.ts +4 -0
- package/src/tx/name-service-ens.ts +207 -0
- package/src/tx/name-service.ts +39 -0
- package/src/tx/recipient.ts +166 -0
- package/src/tx/send-tx.ts +55 -0
- package/src/tx/sender.ts +82 -0
- package/src/tx/types.ts +153 -0
- package/src/tx/validate.ts +55 -0
- package/tsconfig.check.json +90 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { Dec } from "@keplr-wallet/unit";
|
|
2
|
+
import { EthereumQueriesImpl } from "@keplr-wallet/stores-eth";
|
|
3
|
+
import { FeeType } from "./types";
|
|
4
|
+
|
|
5
|
+
// --- Constants ---
|
|
6
|
+
export const GWEI = new Dec(10 ** 9);
|
|
7
|
+
export const ETH_FEE_HISTORY_BLOCK_COUNT = 20;
|
|
8
|
+
export const ETH_FEE_HISTORY_REWARD_PERCENTILES = [20, 40, 60];
|
|
9
|
+
export const MAX_PRIORITY_FEE_UPPER_BOUND = new Dec(20).mul(GWEI);
|
|
10
|
+
export const MAX_PRIORITY_FEE_UPPER_BOUND_FOR_POLYGON = new Dec(100).mul(GWEI);
|
|
11
|
+
export const ETH_FEE_SETTINGS_BY_FEE_TYPE: Record<
|
|
12
|
+
FeeType,
|
|
13
|
+
{
|
|
14
|
+
percentile: number;
|
|
15
|
+
baseFeePercentageMultiplier: Dec;
|
|
16
|
+
}
|
|
17
|
+
> = {
|
|
18
|
+
low: {
|
|
19
|
+
percentile: ETH_FEE_HISTORY_REWARD_PERCENTILES[0],
|
|
20
|
+
baseFeePercentageMultiplier: new Dec(1),
|
|
21
|
+
},
|
|
22
|
+
average: {
|
|
23
|
+
percentile: ETH_FEE_HISTORY_REWARD_PERCENTILES[1],
|
|
24
|
+
baseFeePercentageMultiplier: new Dec(1.25),
|
|
25
|
+
},
|
|
26
|
+
high: {
|
|
27
|
+
percentile: ETH_FEE_HISTORY_REWARD_PERCENTILES[2],
|
|
28
|
+
baseFeePercentageMultiplier: new Dec(1.5),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const ETH_FEE_HISTORY_NEWEST_BLOCK = "latest";
|
|
32
|
+
|
|
33
|
+
// --- Result Type ---
|
|
34
|
+
export type EIP1559TxFees = {
|
|
35
|
+
maxPriorityFeePerGas?: Dec;
|
|
36
|
+
maxFeePerGas?: Dec;
|
|
37
|
+
gasPrice?: Dec;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// --- Pure Functions ---
|
|
41
|
+
|
|
42
|
+
export function getMaxPriorityFeeUpperBound(chainId: string): Dec {
|
|
43
|
+
return chainId === "eip155:137"
|
|
44
|
+
? MAX_PRIORITY_FEE_UPPER_BOUND_FOR_POLYGON
|
|
45
|
+
: MAX_PRIORITY_FEE_UPPER_BOUND;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function calculateOptimalMaxPriorityFeePerGas(
|
|
49
|
+
ethereumQueries: EthereumQueriesImpl,
|
|
50
|
+
feeType: FeeType,
|
|
51
|
+
chainId: string
|
|
52
|
+
): Dec {
|
|
53
|
+
const feeHistoryQuery =
|
|
54
|
+
ethereumQueries.queryEthereumFeeHistory.getQueryByFeeHistoryParams(
|
|
55
|
+
ETH_FEE_HISTORY_BLOCK_COUNT,
|
|
56
|
+
ETH_FEE_HISTORY_NEWEST_BLOCK,
|
|
57
|
+
ETH_FEE_HISTORY_REWARD_PERCENTILES
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const reasonableMaxPriorityFeePerGas =
|
|
61
|
+
feeHistoryQuery.reasonableMaxPriorityFeePerGas;
|
|
62
|
+
const maxPriorityFeePerGas =
|
|
63
|
+
ethereumQueries.queryEthereumMaxPriorityFee.maxPriorityFeePerGas;
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
reasonableMaxPriorityFeePerGas &&
|
|
67
|
+
reasonableMaxPriorityFeePerGas.length > 0
|
|
68
|
+
) {
|
|
69
|
+
const percentile = ETH_FEE_SETTINGS_BY_FEE_TYPE[feeType].percentile;
|
|
70
|
+
const targetPercentileData = reasonableMaxPriorityFeePerGas.find(
|
|
71
|
+
(item) => item.percentile === percentile
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (targetPercentileData) {
|
|
75
|
+
const historyBasedFee = new Dec(targetPercentileData.value);
|
|
76
|
+
const networkSuggestedFee = new Dec(
|
|
77
|
+
BigInt(maxPriorityFeePerGas ?? "0x0")
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const higherFee = historyBasedFee.gt(networkSuggestedFee)
|
|
81
|
+
? historyBasedFee
|
|
82
|
+
: networkSuggestedFee;
|
|
83
|
+
|
|
84
|
+
const upperBound = getMaxPriorityFeeUpperBound(chainId);
|
|
85
|
+
|
|
86
|
+
if (higherFee.gt(upperBound)) {
|
|
87
|
+
return upperBound;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return higherFee;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (maxPriorityFeePerGas) {
|
|
95
|
+
const multiplier =
|
|
96
|
+
ETH_FEE_SETTINGS_BY_FEE_TYPE[feeType].baseFeePercentageMultiplier;
|
|
97
|
+
return new Dec(BigInt(maxPriorityFeePerGas)).mul(multiplier);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return new Dec(0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// --- Query UI State ---
|
|
104
|
+
export type EIP1559QueryUIState = {
|
|
105
|
+
warning?: Error;
|
|
106
|
+
isLoading: boolean;
|
|
107
|
+
isBlocked: boolean;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export function getEIP1559QueryUIState(
|
|
111
|
+
ethereumQueries: EthereumQueriesImpl,
|
|
112
|
+
chainId: string
|
|
113
|
+
): EIP1559QueryUIState {
|
|
114
|
+
let warning: Error | undefined;
|
|
115
|
+
let isLoading = false;
|
|
116
|
+
|
|
117
|
+
const blockQuery =
|
|
118
|
+
ethereumQueries.queryEthereumBlock.getQueryByBlockNumberOrTag(
|
|
119
|
+
ETH_FEE_HISTORY_NEWEST_BLOCK
|
|
120
|
+
);
|
|
121
|
+
if (blockQuery.error) {
|
|
122
|
+
warning = new Error(`Failed to fetch latest block. chain id: ${chainId}`);
|
|
123
|
+
}
|
|
124
|
+
if (blockQuery.isFetching) {
|
|
125
|
+
isLoading = true;
|
|
126
|
+
}
|
|
127
|
+
if (!blockQuery.response) {
|
|
128
|
+
return { warning, isLoading, isBlocked: true };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const feeHistoryQuery =
|
|
132
|
+
ethereumQueries.queryEthereumFeeHistory.getQueryByFeeHistoryParams(
|
|
133
|
+
ETH_FEE_HISTORY_BLOCK_COUNT,
|
|
134
|
+
ETH_FEE_HISTORY_NEWEST_BLOCK,
|
|
135
|
+
ETH_FEE_HISTORY_REWARD_PERCENTILES
|
|
136
|
+
);
|
|
137
|
+
const maxPriorityFeePerGasQuery = ethereumQueries.queryEthereumMaxPriorityFee;
|
|
138
|
+
|
|
139
|
+
if (feeHistoryQuery.error && maxPriorityFeePerGasQuery.error) {
|
|
140
|
+
warning = new Error(
|
|
141
|
+
`Failed to fetch both fee history and max priority fee. chain id: ${chainId}`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
if (feeHistoryQuery.isFetching || maxPriorityFeePerGasQuery.isFetching) {
|
|
145
|
+
isLoading = true;
|
|
146
|
+
}
|
|
147
|
+
if (!feeHistoryQuery.response || !maxPriorityFeePerGasQuery.response) {
|
|
148
|
+
return { warning, isLoading, isBlocked: true };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const gasPriceQuery = ethereumQueries.queryEthereumGasPrice;
|
|
152
|
+
if (gasPriceQuery.error) {
|
|
153
|
+
warning = new Error(`Failed to fetch gas price. chain id: ${chainId}`);
|
|
154
|
+
}
|
|
155
|
+
if (gasPriceQuery.isFetching) {
|
|
156
|
+
isLoading = true;
|
|
157
|
+
}
|
|
158
|
+
if (!gasPriceQuery.response) {
|
|
159
|
+
return { warning, isLoading, isBlocked: true };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return { warning, isLoading, isBlocked: false };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// --- L1 Data Fee ---
|
|
166
|
+
|
|
167
|
+
export function getL1DataFeeToAdd(
|
|
168
|
+
hasOpStackFeature: boolean,
|
|
169
|
+
l1DataFee: Dec | undefined
|
|
170
|
+
): Dec {
|
|
171
|
+
return hasOpStackFeature ? l1DataFee ?? new Dec(0) : new Dec(0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// --- Fee Computation ---
|
|
175
|
+
|
|
176
|
+
export function computeEIP1559TxFees(
|
|
177
|
+
ethereumQueries: EthereumQueriesImpl,
|
|
178
|
+
feeType: FeeType,
|
|
179
|
+
chainId: string,
|
|
180
|
+
customMaxPriorityFeePerGas?: Dec
|
|
181
|
+
): EIP1559TxFees {
|
|
182
|
+
const block = ethereumQueries.queryEthereumBlock.getQueryByBlockNumberOrTag(
|
|
183
|
+
ETH_FEE_HISTORY_NEWEST_BLOCK
|
|
184
|
+
).block;
|
|
185
|
+
const latestBaseFeePerGas = parseInt(block?.baseFeePerGas ?? "0");
|
|
186
|
+
if (latestBaseFeePerGas !== 0) {
|
|
187
|
+
const multiplier =
|
|
188
|
+
ETH_FEE_SETTINGS_BY_FEE_TYPE[feeType].baseFeePercentageMultiplier;
|
|
189
|
+
const baseFeePerGasDec = new Dec(latestBaseFeePerGas);
|
|
190
|
+
const baseFeePerGasWithMargin = baseFeePerGasDec.mul(multiplier);
|
|
191
|
+
const maxPriorityFeePerGas =
|
|
192
|
+
customMaxPriorityFeePerGas ??
|
|
193
|
+
calculateOptimalMaxPriorityFeePerGas(ethereumQueries, feeType, chainId);
|
|
194
|
+
const maxFeePerGas = baseFeePerGasWithMargin.add(maxPriorityFeePerGas);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas.truncateDec(),
|
|
198
|
+
maxFeePerGas: maxFeePerGas.truncateDec(),
|
|
199
|
+
};
|
|
200
|
+
} else {
|
|
201
|
+
const gasPrice = ethereumQueries.queryEthereumGasPrice.gasPrice;
|
|
202
|
+
|
|
203
|
+
if (gasPrice != null) {
|
|
204
|
+
const multipliedGasPrice = new Dec(BigInt(gasPrice)).mul(
|
|
205
|
+
ETH_FEE_SETTINGS_BY_FEE_TYPE[feeType].baseFeePercentageMultiplier
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
gasPrice: multipliedGasPrice,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
gasPrice: new Dec(0),
|
|
216
|
+
};
|
|
217
|
+
}
|