@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.
Files changed (72) hide show
  1. package/.eslintrc.json +14 -0
  2. package/build/index.d.ts +1 -0
  3. package/build/index.js +18 -0
  4. package/build/index.js.map +1 -0
  5. package/build/tx/amount.d.ts +27 -0
  6. package/build/tx/amount.js +238 -0
  7. package/build/tx/amount.js.map +1 -0
  8. package/build/tx/chain.d.ts +10 -0
  9. package/build/tx/chain.js +37 -0
  10. package/build/tx/chain.js.map +1 -0
  11. package/build/tx/errors.d.ts +30 -0
  12. package/build/tx/errors.js +84 -0
  13. package/build/tx/errors.js.map +1 -0
  14. package/build/tx/evm-fee-utils.d.ts +28 -0
  15. package/build/tx/evm-fee-utils.js +133 -0
  16. package/build/tx/evm-fee-utils.js.map +1 -0
  17. package/build/tx/fee.d.ts +61 -0
  18. package/build/tx/fee.js +523 -0
  19. package/build/tx/fee.js.map +1 -0
  20. package/build/tx/gas-simulator.d.ts +89 -0
  21. package/build/tx/gas-simulator.js +465 -0
  22. package/build/tx/gas-simulator.js.map +1 -0
  23. package/build/tx/gas.d.ts +12 -0
  24. package/build/tx/gas.js +84 -0
  25. package/build/tx/gas.js.map +1 -0
  26. package/build/tx/index.d.ts +13 -0
  27. package/build/tx/index.js +30 -0
  28. package/build/tx/index.js.map +1 -0
  29. package/build/tx/internal.d.ts +3 -0
  30. package/build/tx/internal.js +3 -0
  31. package/build/tx/internal.js.map +1 -0
  32. package/build/tx/name-service-ens.d.ts +40 -0
  33. package/build/tx/name-service-ens.js +189 -0
  34. package/build/tx/name-service-ens.js.map +1 -0
  35. package/build/tx/name-service.d.ts +20 -0
  36. package/build/tx/name-service.js +20 -0
  37. package/build/tx/name-service.js.map +1 -0
  38. package/build/tx/recipient.d.ts +35 -0
  39. package/build/tx/recipient.js +131 -0
  40. package/build/tx/recipient.js.map +1 -0
  41. package/build/tx/send-tx.d.ts +13 -0
  42. package/build/tx/send-tx.js +24 -0
  43. package/build/tx/send-tx.js.map +1 -0
  44. package/build/tx/sender.d.ts +12 -0
  45. package/build/tx/sender.js +73 -0
  46. package/build/tx/sender.js.map +1 -0
  47. package/build/tx/types.d.ts +102 -0
  48. package/build/tx/types.js +3 -0
  49. package/build/tx/types.js.map +1 -0
  50. package/build/tx/validate.d.ts +11 -0
  51. package/build/tx/validate.js +37 -0
  52. package/build/tx/validate.js.map +1 -0
  53. package/package.json +40 -0
  54. package/src/index.ts +1 -0
  55. package/src/tx/amount.ts +273 -0
  56. package/src/tx/chain.ts +31 -0
  57. package/src/tx/errors.ts +79 -0
  58. package/src/tx/evm-fee-utils.ts +217 -0
  59. package/src/tx/fee.ts +622 -0
  60. package/src/tx/gas-simulator.ts +567 -0
  61. package/src/tx/gas.ts +93 -0
  62. package/src/tx/index.ts +13 -0
  63. package/src/tx/internal.ts +4 -0
  64. package/src/tx/name-service-ens.ts +207 -0
  65. package/src/tx/name-service.ts +39 -0
  66. package/src/tx/recipient.ts +166 -0
  67. package/src/tx/send-tx.ts +55 -0
  68. package/src/tx/sender.ts +82 -0
  69. package/src/tx/types.ts +153 -0
  70. package/src/tx/validate.ts +55 -0
  71. package/tsconfig.check.json +90 -0
  72. 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
+ }