@valve-tech/gas-oracle 0.7.0 → 0.8.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 (44) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +115 -16
  3. package/dist/block-position.d.ts +3 -3
  4. package/dist/block-position.d.ts.map +1 -1
  5. package/dist/block-position.js +27 -19
  6. package/dist/block-position.js.map +1 -1
  7. package/dist/classify-tip.d.ts +33 -0
  8. package/dist/classify-tip.d.ts.map +1 -0
  9. package/dist/classify-tip.js +52 -0
  10. package/dist/classify-tip.js.map +1 -0
  11. package/dist/inclusion-labels.d.ts +30 -0
  12. package/dist/inclusion-labels.d.ts.map +1 -0
  13. package/dist/inclusion-labels.js +35 -0
  14. package/dist/inclusion-labels.js.map +1 -0
  15. package/dist/index.d.ts +7 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +10 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/math.d.ts +1 -1
  20. package/dist/math.d.ts.map +1 -1
  21. package/dist/math.js +17 -17
  22. package/dist/math.js.map +1 -1
  23. package/dist/oracle.d.ts +2 -2
  24. package/dist/oracle.d.ts.map +1 -1
  25. package/dist/oracle.js +7 -6
  26. package/dist/oracle.js.map +1 -1
  27. package/dist/presets.d.ts +36 -0
  28. package/dist/presets.d.ts.map +1 -0
  29. package/dist/presets.js +27 -0
  30. package/dist/presets.js.map +1 -0
  31. package/dist/replacement.d.ts +80 -0
  32. package/dist/replacement.d.ts.map +1 -0
  33. package/dist/replacement.js +114 -0
  34. package/dist/replacement.js.map +1 -0
  35. package/dist/types.d.ts +49 -5
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/types.js +57 -1
  38. package/dist/types.js.map +1 -1
  39. package/dist/viem-transport.d.ts +1 -1
  40. package/dist/viem-transport.d.ts.map +1 -1
  41. package/dist/viem-transport.js +11 -5
  42. package/dist/viem-transport.js.map +1 -1
  43. package/package.json +2 -2
  44. package/skills/gas-oracle-integration/SKILL.md +105 -12
package/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ All notable changes to `@valve-tech/gas-oracle` are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [0.8.0] — 2026-05-06
9
+
10
+ Consumes `@valve-tech/chain-source@0.8.0`'s WS-aware `ChainSource` transparently. Adds upstream helpers (replacement / classifyTip / inclusion labels), chain presets (PulseChain), const-namespace exports, and a bigint migration of public numeric fields.
11
+
12
+ ### Added
13
+
14
+ - **Replacement helpers** (`replacement.ts`): `minimumReplacementFee(current, txType)`, `bumpForReplacement(currentGas, targetGas)`, `recommendBumpTier(snapshot, stuckTx, options?)` with three named strategies (`BumpStrategy.cheapestThatLands` / `oneStepFasterThanRecommended` / `instant`). Outpace correction via optional `stuckTx.identifier` reads `snapshot.mempoolSamples` to find the tip needed to outpace the stuck tx in the live distribution, on top of the EIP-1559 +10% protocol floor (verified against geth/reth/PulseChain go-pulse sources).
15
+ - **`classifyTip(snapshot, tipWei)`** (`classify-tip.ts`): inverse of `tipForBlockPosition`. Returns `{ tier, requiredForNextTier, percentile, rank, gasFromTop }`.
16
+ - **Inclusion labels** (`inclusion-labels.ts`): `defaultInclusionLabels` (Record<TierName, string>) and `inclusionLabel(tier, overrides?)` for locale/branded copy without forking.
17
+ - **Chain presets** (`presets.ts`): `chainPresets.pulsechain` (chainId: 369, priorityModel: PriorityModel.flat) plus `presetForChainId(chainId)` runtime lookup.
18
+ - **Const-namespace exports**: `PriorityModel`, `TierName`, `Trend`, `TxType` are now exported as both values (const namespaces) and types. Use `PriorityModel.flat` instead of `'flat'` etc. `TIER_LADDER` (canonical slow→instant ordering) also exported from `types.ts`.
19
+ - **`mempoolSamples: TipSample[]`** on `GasOracleState`. Producer-local — wire publishers should strip before serializing (same convention as `ring`).
20
+
21
+ ### Changed
22
+
23
+ - **`priorityModel` default flips from `'flat'` to `PriorityModel.eip1559`**. Most chains honor the EIP-2718 type byte and the EIP-1559 fee-market; the default is now correct for the majority case. PulseChain (chain 369) becomes the explicit exception — set `priorityModel: PriorityModel.flat` (or use `...chainPresets.pulsechain`).
24
+ - **BigInt migration of public numeric fields**: `MempoolStats.pendingCount`, `MempoolStats.queuedCount`, `BlockPositionQuery.rank`, `BlockPositionQuery.percentile`, `BlockPositionResult.rank`, `CreateGasOracleOptions.pollIntervalMs` are now `bigint`. Identifier-like fields (`chainId`, EIP-2718 type bytes) stay `number`.
25
+
26
+ ### Migration notes
27
+
28
+ - Examples that previously omitted `priorityModel` silently get `PriorityModel.eip1559` after upgrade. Verify against your target chain.
29
+ - Math operations on the migrated bigint fields need `n` literals (`0n`, `1n`, etc.) and integer-floor division semantics.
30
+ - `pollIntervalMs: 5000` becomes `pollIntervalMs: 5000n`.
31
+
8
32
  ## [0.7.0] — 2026-05-06
9
33
 
10
34
  ### Changed
package/README.md CHANGED
@@ -28,7 +28,7 @@ yarn add @valve-tech/gas-oracle viem
28
28
  ```ts
29
29
  import { createPublicClient, http, parseEther } from 'viem'
30
30
  import { mainnet } from 'viem/chains'
31
- import { createGasOracle } from '@valve-tech/gas-oracle'
31
+ import { createGasOracle, PriorityModel } from '@valve-tech/gas-oracle'
32
32
 
33
33
  const client = createPublicClient({ chain: mainnet, transport: http() })
34
34
 
@@ -36,7 +36,7 @@ const oracle = createGasOracle({
36
36
  client,
37
37
  chainId: 1,
38
38
  priorityFeeDecayCap: parseEther('0.125'), // 12.5%/block, EIP-1559 parity
39
- priorityModel: 'eip1559', // 'flat' for chains whose validators charge tips instead of burning them
39
+ // priorityModel defaults to PriorityModel.eip1559 explicit only if you need to override
40
40
  })
41
41
 
42
42
  oracle.subscribe((state) => {
@@ -73,7 +73,7 @@ Tier mapping in the gas-weighted percentile distribution:
73
73
 
74
74
  `slow` always reads from the full distribution (legacy + 1559) so legacy
75
75
  senders can still find the lane they actually live in. Under
76
- `priorityModel: 'eip1559'`, the paying-lane tiers (`standard`/`fast`/
76
+ `PriorityModel.eip1559`, the paying-lane tiers (`standard`/`fast`/
77
77
  `instant`) draw from type-2+ samples only — legacy spam can't suppress
78
78
  them.
79
79
 
@@ -95,19 +95,32 @@ priorityFeeDecayCap: null // uncapped — track raw mempool
95
95
  Validated at construction; out-of-range values throw. Upside is always
96
96
  unclamped — real spikes propagate immediately.
97
97
 
98
- ### `priorityModel`
98
+ ### Choosing `priorityModel`
99
99
 
100
- Where the chain's inclusion logic draws its priority cutoff in the
101
- EIP-2718 type space:
100
+ The default is `PriorityModel.eip1559` and is correct for every chain whose validators honor the EIP-2718 type byte and the EIP-1559 fee-market shape. **You should only override this if you've verified your target chain's validators are extractive** that is, they ignore the type byte and maximize fee per gas regardless of tx envelope.
102
101
 
103
- - `'flat'` every tx contributes equally to the gas-weighted
102
+ The canonical example is **PulseChain (chain 369)**: extractive validators mean the percentile math has to draw from the full tx distribution (`PriorityModel.flat`) instead of filtering to type-2+ samples. Setting the wrong model here silently under-prices, and your tx stalls.
103
+
104
+ For chains we know about, the `chainPresets` entry-point handles this for you:
105
+
106
+ ```ts
107
+ import { createGasOracle, chainPresets } from '@valve-tech/gas-oracle'
108
+
109
+ const oracle = createGasOracle({
110
+ client,
111
+ ...chainPresets.pulsechain, // chainId: 369, priorityModel: PriorityModel.flat
112
+ })
113
+ ```
114
+
115
+ Mechanics:
116
+
117
+ - `PriorityModel.flat` — every tx contributes equally to the gas-weighted
104
118
  distribution. Right for extractive validators (PulseChain, etc.)
105
119
  that ignore the type byte and just maximize fee per gas.
106
- - `'eip1559'` — type 2+ samples drive the paying-lane tiers (standard/
107
- fast/instant); `slow` still draws from the full distribution. Right
108
- for chains that honor EIP-1559 ordering (Ethereum, most L2s).
109
-
110
- Default `'flat'` (most conservative — never under-counts spam).
120
+ - `PriorityModel.eip1559` — type 2+ samples drive the paying-lane tiers
121
+ (standard/fast/instant); `slow` still draws from the full
122
+ distribution. Right for chains that honor EIP-1559 ordering
123
+ (Ethereum, most L2s).
111
124
 
112
125
  ### `baseFeeLivenessBlocks`
113
126
 
@@ -240,12 +253,12 @@ For callers who need a single fee snapshot without a long-lived
240
253
  oracle (typical tx-submit flow):
241
254
 
242
255
  ```ts
243
- import { sampleGasFees } from '@valve-tech/gas-oracle'
256
+ import { sampleGasFees, PriorityModel } from '@valve-tech/gas-oracle'
244
257
 
245
258
  const snapshot = await sampleGasFees({
246
259
  client,
247
260
  chainId: 1,
248
- priorityModel: 'eip1559',
261
+ priorityModel: PriorityModel.eip1559,
249
262
  })
250
263
  const tip = snapshot?.tiers.fast.maxPriorityFeePerGas
251
264
  ```
@@ -309,6 +322,90 @@ the same union `computeTiers` reads. The viem-actions extension
309
322
  exposes `client.tipForBlockPosition(query)` which assembles this
310
323
  distribution for you from the oracle's state.
311
324
 
325
+ ## Replacement workflow
326
+
327
+ When a tx gets stuck and you need to bump it past the EIP-1559 protocol
328
+ replacement floor (and optionally past the live mempool distribution):
329
+
330
+ ```ts
331
+ import {
332
+ createGasOracle,
333
+ recommendBumpTier,
334
+ bumpForReplacement,
335
+ BumpStrategy,
336
+ } from '@valve-tech/gas-oracle'
337
+
338
+ // 1. Pick a tier to bump to:
339
+ const tier = recommendBumpTier(
340
+ state,
341
+ { priorityTip: stuckTx.maxPriorityFeePerGas, identifier: { hash: stuckTx.hash } },
342
+ { strategy: BumpStrategy.cheapestThatLands },
343
+ )
344
+
345
+ if (tier === null) {
346
+ // Stuck tx is already paying above the top of the tier ladder, or
347
+ // the snapshot has no tip data. Caller's call: hold, or push instant.
348
+ return
349
+ }
350
+
351
+ // 2. Compute the gas object that satisfies both the protocol floor and the target tier:
352
+ const target = state.tiers[tier]
353
+ const gas = bumpForReplacement(
354
+ { maxFeePerGas: stuckTx.maxFeePerGas, maxPriorityFeePerGas: stuckTx.maxPriorityFeePerGas },
355
+ { maxFeePerGas: target.maxFeePerGas, maxPriorityFeePerGas: target.maxPriorityFeePerGas },
356
+ )
357
+
358
+ // 3. Send the replacement
359
+ walletClient.sendTransaction({ ...stuckTx, ...gas })
360
+ ```
361
+
362
+ ## Tip classification
363
+
364
+ Inverse of `tipForBlockPosition`: given a tip, find where it lands in the
365
+ live distribution and which named tier it falls in.
366
+
367
+ ```ts
368
+ import { classifyTip } from '@valve-tech/gas-oracle'
369
+
370
+ const result = classifyTip(state, myTip)
371
+ // result.tier — TierName | null (null if below slow)
372
+ // result.requiredForNextTier — bigint floor of next tier above (null at instant)
373
+ // result.percentile — bigint 0-100 (0 = top, 100 = bottom)
374
+ // result.rank — bigint 0-indexed from top
375
+ // result.gasFromTop — bigint accumulated gas above this tip
376
+ ```
377
+
378
+ ## UI labels
379
+
380
+ ```ts
381
+ import { defaultInclusionLabels, inclusionLabel, TierName } from '@valve-tech/gas-oracle'
382
+
383
+ defaultInclusionLabels[TierName.standard] // 'Next block'
384
+
385
+ // Locale / branded copy via partial overrides — no fork:
386
+ const es = { [TierName.standard]: 'Próximo bloque' }
387
+ inclusionLabel(TierName.standard, es) // 'Próximo bloque'
388
+ inclusionLabel(TierName.slow, es) // falls back to default English
389
+ ```
390
+
391
+ ## Chain presets
392
+
393
+ ```ts
394
+ import { createGasOracle, chainPresets, presetForChainId } from '@valve-tech/gas-oracle'
395
+
396
+ // Static — direct preset access
397
+ createGasOracle({ client, ...chainPresets.pulsechain })
398
+
399
+ // Dynamic — runtime lookup by chainId
400
+ const preset = presetForChainId(chainId)
401
+ createGasOracle({ client, chainId, ...preset })
402
+ ```
403
+
404
+ PulseChain (chain 369) is the only entry shipped today. Adding more
405
+ requires verifying the chain's actual validator behavior against
406
+ block-level data; the default (eip1559) is correct for every chain we
407
+ haven't proven otherwise.
408
+
312
409
  ## viem integration
313
410
 
314
411
  ### Subpath: `@valve-tech/gas-oracle/viem-actions`
@@ -317,12 +414,13 @@ Extension surface for callers who want explicit access to tier shapes:
317
414
 
318
415
  ```ts
319
416
  import { gasOracleActions } from '@valve-tech/gas-oracle/viem-actions'
417
+ import { PriorityModel } from '@valve-tech/gas-oracle'
320
418
 
321
419
  const client = createPublicClient({ chain: mainnet, transport: http() })
322
420
  .extend(gasOracleActions({
323
421
  chainId: 1,
324
422
  priorityFeeDecayCap: parseEther('0.125'),
325
- priorityModel: 'eip1559',
423
+ priorityModel: PriorityModel.eip1559,
326
424
  }))
327
425
 
328
426
  await client.getGasTiers() // full snapshot
@@ -343,11 +441,12 @@ work better* — `useFeeData`, `walletClient.sendTransaction({...})`,
343
441
 
344
442
  ```ts
345
443
  import { withGasOracle } from '@valve-tech/gas-oracle/viem-transport'
444
+ import { PriorityModel } from '@valve-tech/gas-oracle'
346
445
 
347
446
  const transport = withGasOracle(http(rpcUrl), {
348
447
  chainId: 1,
349
448
  priorityFeeDecayCap: parseEther('0.125'),
350
- priorityModel: 'eip1559',
449
+ priorityModel: PriorityModel.eip1559,
351
450
  intercept: {
352
451
  eth_gasFeeEstimate: true, // additive (default on)
353
452
  eth_maxPriorityFeePerGas: 'fast', // tier required for standard methods
@@ -48,10 +48,10 @@ import type { TxIdentifier } from './mempool.js';
48
48
  */
49
49
  export type BlockPositionQuery = {
50
50
  kind: 'rank';
51
- rank: number;
51
+ rank: bigint;
52
52
  } | {
53
53
  kind: 'percentile';
54
- percentile: number;
54
+ percentile: bigint;
55
55
  } | {
56
56
  kind: 'gasFromTop';
57
57
  gas: bigint;
@@ -79,7 +79,7 @@ export interface BlockPositionResult {
79
79
  */
80
80
  pivot: TipSample | null;
81
81
  /** Approximate rank of the resolved position, 0-indexed from top. */
82
- rank: number;
82
+ rank: bigint;
83
83
  /** Approximate gas-from-top of the resolved position. */
84
84
  gasFromTop: bigint;
85
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"block-position.d.ts","sourceRoot":"","sources":["../src/block-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAAE,CAAA;AAExC,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAA;CACnB;AAkDD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,SAAS,EAAE,EACpB,OAAO,kBAAkB,KACxB,mBA0DF,CAAA"}
1
+ {"version":3,"file":"block-position.d.ts","sourceRoot":"","sources":["../src/block-position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAAE,CAAA;AAExC,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,KAAK,EAAE,SAAS,GAAG,IAAI,CAAA;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAA;CACnB;AAoDD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,SAAS,EAAE,EACpB,OAAO,kBAAkB,KACxB,mBAiEF,CAAA"}
@@ -39,31 +39,33 @@ const matchesIdentifier = (sample, id) => {
39
39
  /**
40
40
  * Walk samples in tip-desc order accumulating gas; return the index
41
41
  * (0-based from top) where cumulative gas first crosses `targetGas`.
42
- * Returns -1 when the target exceeds the sum of all gas (the position
42
+ * Returns -1n when the target exceeds the sum of all gas (the position
43
43
  * is below the whole distribution).
44
44
  */
45
45
  const indexAtGasOffset = (sorted, targetGas) => {
46
46
  if (targetGas <= 0n)
47
- return 0;
47
+ return 0n;
48
48
  let cumulative = 0n;
49
- for (let i = 0; i < sorted.length; i += 1) {
50
- cumulative += sorted[i].gas;
49
+ const len = BigInt(sorted.length);
50
+ for (let i = 0n; i < len; i += 1n) {
51
+ cumulative += sorted[Number(i)].gas;
51
52
  if (cumulative > targetGas)
52
53
  return i;
53
54
  }
54
- return -1;
55
+ return -1n;
55
56
  };
56
57
  const sumGasUpTo = (sorted, indexExclusive) => {
57
58
  let g = 0n;
58
- const upper = Math.min(indexExclusive, sorted.length);
59
- for (let i = 0; i < upper; i += 1)
60
- g += sorted[i].gas;
59
+ const len = BigInt(sorted.length);
60
+ const upper = indexExclusive < len ? indexExclusive : len;
61
+ for (let i = 0n; i < upper; i += 1n)
62
+ g += sorted[Number(i)].gas;
61
63
  return g;
62
64
  };
63
65
  const empty = () => ({
64
66
  requiredTip: 0n,
65
67
  pivot: null,
66
- rank: 0,
68
+ rank: 0n,
67
69
  gasFromTop: 0n,
68
70
  });
69
71
  /**
@@ -80,6 +82,7 @@ export const tipForBlockPosition = (samples, query) => {
80
82
  if (samples.length === 0)
81
83
  return empty();
82
84
  const sorted = sortByTipDesc(samples);
85
+ const len = BigInt(sorted.length);
83
86
  let pivotIndex;
84
87
  let beatPivot; // true = outbid (tip+1), false = undercut (tip-1)
85
88
  switch (query.kind) {
@@ -89,12 +92,16 @@ export const tipForBlockPosition = (samples, query) => {
89
92
  break;
90
93
  }
91
94
  case 'percentile': {
92
- // 0% = top of block (highest tip); 100% = bottom. Clamp to [0, 100].
93
- const pct = Math.min(100, Math.max(0, query.percentile));
94
- pivotIndex = Math.floor((sorted.length * pct) / 100);
95
+ // 0% = top of block (highest tip); 100% = bottom. Clamp to [0n, 100n].
96
+ const pct = query.percentile < 0n
97
+ ? 0n
98
+ : query.percentile > 100n
99
+ ? 100n
100
+ : query.percentile;
101
+ pivotIndex = (len * pct) / 100n;
95
102
  // Edge: percentile=100 lands at length, which is "below everything"
96
- if (pivotIndex >= sorted.length)
97
- pivotIndex = sorted.length - 1;
103
+ if (pivotIndex >= len)
104
+ pivotIndex = len - 1n;
98
105
  beatPivot = true;
99
106
  break;
100
107
  }
@@ -105,21 +112,22 @@ export const tipForBlockPosition = (samples, query) => {
105
112
  }
106
113
  case 'aheadOf':
107
114
  case 'behind': {
108
- pivotIndex = sorted.findIndex((s) => matchesIdentifier(s, query.tx));
115
+ const found = sorted.findIndex((s) => matchesIdentifier(s, query.tx));
116
+ pivotIndex = found === -1 ? -1n : BigInt(found);
109
117
  beatPivot = query.kind === 'aheadOf';
110
118
  break;
111
119
  }
112
120
  }
113
- if (pivotIndex < 0 || pivotIndex >= sorted.length) {
121
+ if (pivotIndex < 0n || pivotIndex >= len) {
114
122
  // Position is below everyone (or pivot not found) — pay nothing in priority
115
123
  return {
116
124
  requiredTip: 0n,
117
125
  pivot: null,
118
- rank: sorted.length,
119
- gasFromTop: sumGasUpTo(sorted, sorted.length),
126
+ rank: len,
127
+ gasFromTop: sumGasUpTo(sorted, len),
120
128
  };
121
129
  }
122
- const pivot = sorted[pivotIndex];
130
+ const pivot = sorted[Number(pivotIndex)];
123
131
  const requiredTip = beatPivot
124
132
  ? pivot.tip + 1n
125
133
  : pivot.tip > 0n
@@ -1 +1 @@
1
- {"version":3,"file":"block-position.js","sourceRoot":"","sources":["../src/block-position.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block-position.js","sourceRoot":"","sources":["../src/block-position.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Inverse of `tipForBlockPosition`. Given a tip and a snapshot, find
3
+ * where the tip would land in the live distribution and which named
4
+ * tier it falls in. Pure: no I/O, no oracle dependency, no wall-clock.
5
+ *
6
+ * Useful for "you priced at the Xth percentile" UI affordances and for
7
+ * post-hoc "why is my tx slow" diagnostics.
8
+ */
9
+ import { TierName, type GasOracleState } from './types.js';
10
+ export interface ClassifyTipResult {
11
+ /**
12
+ * Named tier the tip falls in. `null` when below `TierName.slow`'s
13
+ * `maxPriorityFeePerGas` floor.
14
+ */
15
+ tier: TierName | null;
16
+ /**
17
+ * `maxPriorityFeePerGas` floor of the next tier above `tier`. `null`
18
+ * when `tier === TierName.instant` (already at top).
19
+ */
20
+ requiredForNextTier: bigint | null;
21
+ /**
22
+ * Approximate percentile in the live distribution (block ring tips +
23
+ * mempool samples), 0n..100n. `0n` = top of block (highest tip);
24
+ * `100n` = bottom. `0n` when distribution empty.
25
+ */
26
+ percentile: bigint;
27
+ /** Approximate rank, 0n-indexed from top. `0n` when distribution empty. */
28
+ rank: bigint;
29
+ /** Accumulated gas above this tip's position. `0n` when empty. */
30
+ gasFromTop: bigint;
31
+ }
32
+ export declare const classifyTip: (snapshot: GasOracleState, tipWei: bigint) => ClassifyTipResult;
33
+ //# sourceMappingURL=classify-tip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify-tip.d.ts","sourceRoot":"","sources":["../src/classify-tip.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,QAAQ,EACR,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAA;IACrB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAA;CACnB;AA4BD,eAAO,MAAM,WAAW,GACtB,UAAU,cAAc,EACxB,QAAQ,MAAM,KACb,iBA0BF,CAAA"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Inverse of `tipForBlockPosition`. Given a tip and a snapshot, find
3
+ * where the tip would land in the live distribution and which named
4
+ * tier it falls in. Pure: no I/O, no oracle dependency, no wall-clock.
5
+ *
6
+ * Useful for "you priced at the Xth percentile" UI affordances and for
7
+ * post-hoc "why is my tx slow" diagnostics.
8
+ */
9
+ import { TIER_LADDER, } from './types.js';
10
+ const tierForTip = (tiers, tipWei) => {
11
+ for (let i = TIER_LADDER.length - 1; i >= 0; i -= 1) {
12
+ const tier = TIER_LADDER[i];
13
+ if (tipWei >= tiers[tier].maxPriorityFeePerGas)
14
+ return tier;
15
+ }
16
+ return null;
17
+ };
18
+ const requiredForNextTierAbove = (tiers, currentTier) => {
19
+ const currentIndex = currentTier ? TIER_LADDER.indexOf(currentTier) : -1;
20
+ const nextIndex = currentIndex + 1;
21
+ if (nextIndex >= TIER_LADDER.length)
22
+ return null;
23
+ return tiers[TIER_LADDER[nextIndex]].maxPriorityFeePerGas;
24
+ };
25
+ const collectDistribution = (snapshot) => [
26
+ ...snapshot.ring.flatMap((block) => block.tips),
27
+ ...snapshot.mempoolSamples,
28
+ ];
29
+ export const classifyTip = (snapshot, tipWei) => {
30
+ const tier = tierForTip(snapshot.tiers, tipWei);
31
+ const requiredForNextTier = requiredForNextTierAbove(snapshot.tiers, tier);
32
+ const samples = collectDistribution(snapshot);
33
+ if (samples.length === 0) {
34
+ return { tier, requiredForNextTier, percentile: 0n, rank: 0n, gasFromTop: 0n };
35
+ }
36
+ // Sort by tip desc, equal-tip arm folded into descending side
37
+ // (matches block-position.ts convention).
38
+ const sorted = [...samples].sort((a, b) => (a.tip > b.tip ? -1 : 1));
39
+ const firstWeakerIndexNum = sorted.findIndex((s) => s.tip <= tipWei);
40
+ const samplesLen = BigInt(sorted.length);
41
+ const rank = firstWeakerIndexNum === -1
42
+ ? samplesLen
43
+ : BigInt(firstWeakerIndexNum);
44
+ // Round-half-away-from-zero percentile, all bigint. samplesLen >= 1n
45
+ // is guaranteed by the early-return on empty samples above.
46
+ const percentile = (rank * 100n + samplesLen / 2n) / samplesLen;
47
+ let gasFromTop = 0n;
48
+ for (let i = 0n; i < rank; i += 1n)
49
+ gasFromTop += sorted[Number(i)].gas;
50
+ return { tier, requiredForNextTier, percentile, rank, gasFromTop };
51
+ };
52
+ //# sourceMappingURL=classify-tip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify-tip.js","sourceRoot":"","sources":["../src/classify-tip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Default English UI copy mapping each tier to a user-facing inclusion
3
+ * label, plus a small helper that resolves a tier with optional partial
4
+ * overrides (locale or branded copy without forking the whole map).
5
+ *
6
+ * Conservative phrasing — labels describe relative position in the next
7
+ * block, not hard guarantees. Real inclusion is probabilistic.
8
+ */
9
+ import { TierName } from './types.js';
10
+ export declare const defaultInclusionLabels: Record<TierName, string>;
11
+ /**
12
+ * Resolve a tier to its inclusion label, falling back to
13
+ * `defaultInclusionLabels` for any tier not present in `overrides`.
14
+ *
15
+ * Locale / branded-copy pattern (no fork required):
16
+ *
17
+ * ```ts
18
+ * const es: Partial<Record<TierName, string>> = {
19
+ * [TierName.standard]: 'Próximo bloque',
20
+ * [TierName.fast]: 'Cabeza del próximo bloque',
21
+ * }
22
+ * inclusionLabel(TierName.standard, es) // 'Próximo bloque'
23
+ * inclusionLabel(TierName.slow, es) // falls back to default English
24
+ * ```
25
+ *
26
+ * Consumers can also fully replace the map by spreading:
27
+ * `const myLabels = { ...defaultInclusionLabels, ...partial }`.
28
+ */
29
+ export declare const inclusionLabel: (tier: TierName, overrides?: Partial<Record<TierName, string>>) => string;
30
+ //# sourceMappingURL=inclusion-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inclusion-labels.d.ts","sourceRoot":"","sources":["../src/inclusion-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAK3D,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,QAAQ,EACd,YAAY,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,KAC5C,MAA2D,CAAA"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Default English UI copy mapping each tier to a user-facing inclusion
3
+ * label, plus a small helper that resolves a tier with optional partial
4
+ * overrides (locale or branded copy without forking the whole map).
5
+ *
6
+ * Conservative phrasing — labels describe relative position in the next
7
+ * block, not hard guarantees. Real inclusion is probabilistic.
8
+ */
9
+ import { TierName } from './types.js';
10
+ export const defaultInclusionLabels = {
11
+ [TierName.slow]: 'Within a few blocks',
12
+ [TierName.standard]: 'Next block',
13
+ [TierName.fast]: 'Top of next block',
14
+ [TierName.instant]: 'Front of next block',
15
+ };
16
+ /**
17
+ * Resolve a tier to its inclusion label, falling back to
18
+ * `defaultInclusionLabels` for any tier not present in `overrides`.
19
+ *
20
+ * Locale / branded-copy pattern (no fork required):
21
+ *
22
+ * ```ts
23
+ * const es: Partial<Record<TierName, string>> = {
24
+ * [TierName.standard]: 'Próximo bloque',
25
+ * [TierName.fast]: 'Cabeza del próximo bloque',
26
+ * }
27
+ * inclusionLabel(TierName.standard, es) // 'Próximo bloque'
28
+ * inclusionLabel(TierName.slow, es) // falls back to default English
29
+ * ```
30
+ *
31
+ * Consumers can also fully replace the map by spreading:
32
+ * `const myLabels = { ...defaultInclusionLabels, ...partial }`.
33
+ */
34
+ export const inclusionLabel = (tier, overrides) => overrides?.[tier] ?? defaultInclusionLabels[tier];
35
+ //# sourceMappingURL=inclusion-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inclusion-labels.js","sourceRoot":"","sources":["../src/inclusion-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,MAAM,CAAC,MAAM,sBAAsB,GAA6B;IAC9D,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,qBAAqB;IACtC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY;IACjC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,mBAAmB;IACpC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB;CAC1C,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,IAAc,EACd,SAA6C,EACrC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -16,9 +16,15 @@ export { createGasOracle, reducePollInputs, sampleGasFees, type CreateGasOracleO
16
16
  export { effectiveTip, computePercentiles, detectTrend, cappedTip, computeTiers, computeBlobBaseFee, flattenTxPool, gasWeightedPercentiles, sortedTips, DEFAULT_PRIORITY_FEE_DECAY_CAP, DEFAULT_BASE_FEE_LIVENESS_BLOCKS, } from './math.js';
17
17
  export { blockToSample, mempoolToSamples, } from './samples.js';
18
18
  export { fetchOracleInputs, fetchHeadBlockNumber, type FeeHistoryResult, type BlockResult, type TxPoolContent, type OraclePollInputs, } from './transport.js';
19
- export type { RawTx, TipPercentiles, TierRecommendation, TierName, Trend, MempoolStats, BlobStats, BlockSample, GasOracleState, TipSample, PriorityModel, PollOptions, } from './types.js';
19
+ export type { RawTx, TipPercentiles, TierRecommendation, MempoolStats, BlobStats, BlockSample, GasOracleState, TipSample, PollOptions, } from './types.js';
20
+ export { PriorityModel, TierName, TIER_LADDER, Trend, TxType } from './types.js';
20
21
  export { normalizeMempool, findByHash, findByAddressNonce, findInMempool, } from './mempool.js';
21
22
  export type { NormalizedMempool, TxIdentifier, MempoolBucket, MempoolHit, } from './mempool.js';
22
23
  export { tipForBlockPosition } from './block-position.js';
23
24
  export type { BlockPositionQuery, BlockPositionResult, } from './block-position.js';
25
+ export { minimumReplacementFee, bumpForReplacement, recommendBumpTier, BumpStrategy, ReplacementBumpPercent, } from './replacement.js';
26
+ export type { RecommendBumpTierOptions, ReplacementGas, } from './replacement.js';
27
+ export { classifyTip, type ClassifyTipResult } from './classify-tip.js';
28
+ export { defaultInclusionLabels, inclusionLabel } from './inclusion-labels.js';
29
+ export { chainPresets, presetForChainId, type ChainPreset, } from './presets.js';
24
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,KAAK,EACL,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,SAAS,EACT,WAAW,EACX,cAAc,EACd,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,SAAS,GACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,KAAK,EACL,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,cAAc,EACd,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGhF,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EACV,wBAAwB,EACxB,cAAc,GACf,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAGvE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAG9E,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,KAAK,WAAW,GACjB,MAAM,cAAc,CAAA"}
package/dist/index.js CHANGED
@@ -16,8 +16,18 @@ export { createGasOracle, reducePollInputs, sampleGasFees, } from './oracle.js';
16
16
  export { effectiveTip, computePercentiles, detectTrend, cappedTip, computeTiers, computeBlobBaseFee, flattenTxPool, gasWeightedPercentiles, sortedTips, DEFAULT_PRIORITY_FEE_DECAY_CAP, DEFAULT_BASE_FEE_LIVENESS_BLOCKS, } from './math.js';
17
17
  export { blockToSample, mempoolToSamples, } from './samples.js';
18
18
  export { fetchOracleInputs, fetchHeadBlockNumber, } from './transport.js';
19
+ // Const-namespace pairs (value + type share the identifier — see types.ts).
20
+ export { PriorityModel, TierName, TIER_LADDER, Trend, TxType } from './types.js';
19
21
  // Mempool inspection
20
22
  export { normalizeMempool, findByHash, findByAddressNonce, findInMempool, } from './mempool.js';
21
23
  // Block-position calculations
22
24
  export { tipForBlockPosition } from './block-position.js';
25
+ // Replacement helpers (same-nonce EIP-1559)
26
+ export { minimumReplacementFee, bumpForReplacement, recommendBumpTier, BumpStrategy, ReplacementBumpPercent, } from './replacement.js';
27
+ // Tip classification (inverse of tipForBlockPosition)
28
+ export { classifyTip } from './classify-tip.js';
29
+ // Inclusion labels (UI copy with optional locale overrides)
30
+ export { defaultInclusionLabels, inclusionLabel } from './inclusion-labels.js';
31
+ // Chain presets (per-chain config overrides for createGasOracle)
32
+ export { chainPresets, presetForChainId, } from './presets.js';
23
33
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,GAGd,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GAKrB,MAAM,gBAAgB,CAAA;AAiBvB,qBAAqB;AACrB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAA;AAQrB,8BAA8B;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,GAGd,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,GAKrB,MAAM,gBAAgB,CAAA;AAcvB,4EAA4E;AAC5E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEhF,qBAAqB;AACrB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,cAAc,CAAA;AAQrB,8BAA8B;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAMzD,4CAA4C;AAC5C,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AAMzB,sDAAsD;AACtD,OAAO,EAAE,WAAW,EAA0B,MAAM,mBAAmB,CAAA;AAEvE,4DAA4D;AAC5D,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE9E,iEAAiE;AACjE,OAAO,EACL,YAAY,EACZ,gBAAgB,GAEjB,MAAM,cAAc,CAAA"}
package/dist/math.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * (legacy txs, EIP-1559 with zero headroom, cold-start cap, post-EIP-4844
8
8
  * blob fee) is handled here rather than at higher layers.
9
9
  */
10
- import type { PriorityModel, RawTx, TierRecommendation, TierName, TipPercentiles, TipSample, Trend } from './types.js';
10
+ import { PriorityModel, TierName, Trend, type RawTx, type TierRecommendation, type TipPercentiles, type TipSample } from './types.js';
11
11
  /** Default priority-fee decay cap = 12.5% / block (EIP-1559 parity). */
12
12
  export declare const DEFAULT_PRIORITY_FEE_DECAY_CAP: bigint;
13
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,KAAK,EACL,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,SAAS,EACT,KAAK,EACN,MAAM,YAAY,CAAA;AAcnB,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,QAAW,CAAA;AAEtD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,IAAI,KAAK,EAAE,SAAS,MAAM,KAAG,MAezD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,KAAG,cASrD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,KAAK,EAAE,EAAE,SAAS,MAAM,KAAG,MAAM,EAK5B,CAAA;AAErC;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,EAAE,KAAG,KAS/C,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,GACpB,QAAQ,MAAM,EACd,gBAAgB,MAAM,EACtB,eAAe,MAAM,GAAG,SAAS,EACjC,0BAA0B,MAAM,GAAG,SAAS,EAC5C,WAAU,MAAM,GAAG,IAAqC,KACvD,MAgBF,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,SAAS,EAAE,EACpB,aAAa,MAAM,EAAE,KACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAkCvB,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,gCAAgC,IAAI,CAAA;AAqDjD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,cAAc,EAAE,SAAS,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,KAAK,CAAA;IACnB,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,GAAG,IAAI,CAAA;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;IACvD,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B,KAAG;IACF,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC3C,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;CA4DxC,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,KAAG,MAY1D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,KAC7D,KAAK,EAOP,CAAA"}
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,aAAa,EACb,QAAQ,EACR,KAAK,EAEL,KAAK,KAAK,EACV,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,YAAY,CAAA;AAcnB,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,QAAW,CAAA;AAEtD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAI,IAAI,KAAK,EAAE,SAAS,MAAM,KAAG,MAezD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,KAAG,cASrD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,KAAK,EAAE,EAAE,SAAS,MAAM,KAAG,MAAM,EAK5B,CAAA;AAErC;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,EAAE,KAAG,KAS/C,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,GACpB,QAAQ,MAAM,EACd,gBAAgB,MAAM,EACtB,eAAe,MAAM,GAAG,SAAS,EACjC,0BAA0B,MAAM,GAAG,SAAS,EAC5C,WAAU,MAAM,GAAG,IAAqC,KACvD,MAgBF,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,SAAS,EAAE,EACpB,aAAa,MAAM,EAAE,KACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAkCvB,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,gCAAgC,IAAI,CAAA;AAmDjD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,WAAW,EAAE,SAAS,EAAE,CAAA;IACxB,cAAc,EAAE,SAAS,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,KAAK,CAAA;IACnB,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,GAAG,IAAI,CAAA;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;IACvD,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B,KAAG;IACF,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC3C,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;CA4DxC,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,KAAG,MAY1D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,KAC7D,KAAK,EAOP,CAAA"}