@rhinestone/service-sdk 0.2.12 → 0.2.14
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/dist/chains.d.ts +22 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/chains.js +41 -12
- package/package.json +1 -1
package/dist/chains.d.ts
CHANGED
|
@@ -13,6 +13,27 @@ export type EstimateGasFeesOptions = {
|
|
|
13
13
|
*/
|
|
14
14
|
mode?: 'legacy';
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* {@link estimateGasFees}' result: viem's EIP-1559 fee values plus the next
|
|
18
|
+
* block's base fee, when it could be read.
|
|
19
|
+
*
|
|
20
|
+
* `baseFeePerGas` is surfaced because `maxFeePerGas` is a submission CAP
|
|
21
|
+
* (`base * baseFeeMultiplierPct + tip`) — the price we are willing to bid up to,
|
|
22
|
+
* not the price a transaction pays (`base + tip`). Billing the cap is correct
|
|
23
|
+
* where a relayer must stay covered if the base fee climbs before inclusion; it
|
|
24
|
+
* is wrong to REPORT to a consumer that compares it against other relayers.
|
|
25
|
+
* Exposing the base fee lets a caller derive the expected price WITHOUT a second
|
|
26
|
+
* eth_feeHistory round trip — every path here already reads it and used to
|
|
27
|
+
* discard it (RHI-4992).
|
|
28
|
+
*
|
|
29
|
+
* `null` when the base fee was unavailable: a non-1559 chain, `mode: 'legacy'`,
|
|
30
|
+
* or a degraded read (already recorded via `recordDegradedEstimate`). Callers
|
|
31
|
+
* must treat null as "unknown" and fall back — never as zero, which would price
|
|
32
|
+
* a cap at the tip alone.
|
|
33
|
+
*/
|
|
34
|
+
export type EstimatedGasFees = FeeValuesEIP1559 & {
|
|
35
|
+
baseFeePerGas: bigint | null;
|
|
36
|
+
};
|
|
16
37
|
/**
|
|
17
38
|
* Estimates gas fees for a chain and returns EIP-1559-shaped fee values.
|
|
18
39
|
*
|
|
@@ -28,5 +49,5 @@ export type EstimateGasFeesOptions = {
|
|
|
28
49
|
* zero. This changes fee estimation only; it does not select a transaction
|
|
29
50
|
* type.
|
|
30
51
|
*/
|
|
31
|
-
export declare function estimateGasFees(client: FeeEstimationClient, chainId: number, options?: EstimateGasFeesOptions): Promise<
|
|
52
|
+
export declare function estimateGasFees(client: FeeEstimationClient, chainId: number, options?: EstimateGasFeesOptions): Promise<EstimatedGasFees>;
|
|
32
53
|
//# sourceMappingURL=chains.d.ts.map
|
package/dist/chains.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAmB,YAAY,EAAE,MAAM,MAAM,CAAA;AAmB3E,oDAAoD;AAMpD,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,YAAY,EACZ,oBAAoB,GAAG,eAAe,CACvC,GACC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;AAEtC,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB,CAAA;
|
|
1
|
+
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAmB,YAAY,EAAE,MAAM,MAAM,CAAA;AAmB3E,oDAAoD;AAMpD,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,YAAY,EACZ,oBAAoB,GAAG,eAAe,CACvC,GACC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA;AAEtC,2CAA2C;AAC3C,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG;IAChD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B,CAAA;AAyUD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAiD3B"}
|
package/dist/chains.js
CHANGED
|
@@ -77,20 +77,36 @@ const FEE_CONFIG_OVERRIDES = {
|
|
|
77
77
|
// gradient — probed live 2026-07-24 over 40 blocks:
|
|
78
78
|
// p1..p10 = 0 p15..p50 = 0.005 gwei
|
|
79
79
|
// so every percentile from 15 up reports the same 0.005, while real fills
|
|
80
|
-
// clear
|
|
81
|
-
// so it demonstrably clears). Sampling anywhere above p10
|
|
82
|
-
// 0.005 and the floor never binds — the tip must be read
|
|
83
|
-
// window median is genuinely 0, so the
|
|
80
|
+
// clear near 0.0014 (third-party solvers are included on-chain at that price
|
|
81
|
+
// ~10.7k times a day, so it demonstrably clears). Sampling anywhere above p10
|
|
82
|
+
// therefore prices at 0.005 and the floor never binds — the tip must be read
|
|
83
|
+
// at p10, where the window median is genuinely 0, so the floor below sets the
|
|
84
|
+
// price.
|
|
84
85
|
[chains_1.plasma.id]: {
|
|
85
86
|
// Explicit, not inherited. Plasma's base fee is ~0 almost always, so this
|
|
86
87
|
// multiplier is free — but "almost" matters: a 7d block replay puts 0.4% of
|
|
87
88
|
// quotes under the base fee one block later at 1.05x, and 1.5% ten blocks
|
|
88
|
-
// later, against 0% at 2.0x. On
|
|
89
|
-
// shared default would silently re-introduce it.
|
|
89
|
+
// later, against 0% at 2.0x. On ~15k bundles/day priced through this chain
|
|
90
|
+
// that is real. Inheriting the shared default would silently re-introduce it.
|
|
90
91
|
baseFeeMultiplierPct: 200n,
|
|
91
92
|
tipPercentile: 10,
|
|
92
93
|
congestedTipPercentile: 25,
|
|
93
|
-
|
|
94
|
+
// 0.0014 gwei — where fills on this chain ACTUALLY clear, re-measured from
|
|
95
|
+
// prod on 2026-07-27 once the previous 0.0017 had deployed and could be
|
|
96
|
+
// checked against reality (it billed 1.25x the clearing price).
|
|
97
|
+
//
|
|
98
|
+
// Measured from the solver that fills ~10.7k plasma bundles/day: it is
|
|
99
|
+
// included at 0.00103 (7d median 0.001364). Inclusion at ~0.001 is therefore
|
|
100
|
+
// demonstrated tens of thousands of times a day. NOTE the on-chain reward
|
|
101
|
+
// percentiles disagree and must not be used here — being gas-weighted they
|
|
102
|
+
// read p25..p90 = 0.005, which is what a minority of gas-heavy transactions
|
|
103
|
+
// pay, not the bar for inclusion.
|
|
104
|
+
//
|
|
105
|
+
// Lowering it cannot hurt includability: plasma's base is ~0, so the cap is
|
|
106
|
+
// `base * 2.0 + floor` and the floor never gates it — the 7d replay reports
|
|
107
|
+
// a 0.00% unincludable rate for every floor from 0.0017 down to 0.0008, at
|
|
108
|
+
// every lag from 1 to 50 blocks. The floor only sets what we CHARGE.
|
|
109
|
+
tipFloorWei: 1400000n,
|
|
94
110
|
},
|
|
95
111
|
};
|
|
96
112
|
// Chains where viem's default base-fee estimate is fine but its tip oracle
|
|
@@ -295,7 +311,12 @@ async function estimateGasFees(client, chainId, options) {
|
|
|
295
311
|
// Equal caps preserve gasPrice as the effective-price ceiling. If a
|
|
296
312
|
// no-priority local fork reports baseFee == gasPrice, the max-fee cap means
|
|
297
313
|
// the actual paid tip remains zero despite this priority-fee allowance.
|
|
298
|
-
|
|
314
|
+
// Legacy has no base-fee component to report.
|
|
315
|
+
return {
|
|
316
|
+
maxFeePerGas: gasPrice,
|
|
317
|
+
maxPriorityFeePerGas: gasPrice,
|
|
318
|
+
baseFeePerGas: null,
|
|
319
|
+
};
|
|
299
320
|
}
|
|
300
321
|
if (HISTORICAL_FEE_CHAINS.has(chainId)) {
|
|
301
322
|
const config = { ...DEFAULT_FEE_CONFIG, ...FEE_CONFIG_OVERRIDES[chainId] };
|
|
@@ -319,6 +340,7 @@ async function estimateGasFees(client, chainId, options) {
|
|
|
319
340
|
return {
|
|
320
341
|
maxFeePerGas: cappedMaxFeePerGas(client, fees, baseFee, chainId, tip, oracleTip),
|
|
321
342
|
maxPriorityFeePerGas: tip,
|
|
343
|
+
baseFeePerGas: baseFee,
|
|
322
344
|
};
|
|
323
345
|
}
|
|
324
346
|
// viem's oracle tip, lifted to an absolute floor — and, for windowed-tip chains,
|
|
@@ -359,6 +381,7 @@ async function estimateViemFeesWithTipFloor(client, chainId, tipFloorWei) {
|
|
|
359
381
|
return {
|
|
360
382
|
maxFeePerGas: cappedMaxFeePerGas(client, fees, history.baseFee, chainId, tip, oracleTip),
|
|
361
383
|
maxPriorityFeePerGas: tip,
|
|
384
|
+
baseFeePerGas: history.baseFee,
|
|
362
385
|
};
|
|
363
386
|
}
|
|
364
387
|
/**
|
|
@@ -533,17 +556,23 @@ async function estimateFeeHistoryGasFees(client, chainId, config) {
|
|
|
533
556
|
//
|
|
534
557
|
// Keeping `priorityFee` is the point. These chains are on the windowed path
|
|
535
558
|
// precisely because their tip oracle is untrustworthy (Plasma's reports
|
|
536
|
-
// 0.005 gwei against a measured 0.
|
|
537
|
-
// would trade a hard failure for a silent ~
|
|
538
|
-
//
|
|
559
|
+
// 0.005 gwei against a measured 0.0014), so falling back to viem wholesale
|
|
560
|
+
// would trade a hard failure for a silent ~3.5x overcharge on the chain
|
|
561
|
+
// carrying the most fills through our pricing. The tip we already computed
|
|
562
|
+
// is the calibrated one.
|
|
539
563
|
recordDegradedEstimate(chainId, 'feehistory_missing_base');
|
|
540
564
|
return {
|
|
541
565
|
maxFeePerGas: await viemFallbackCap(client, config, priorityFee),
|
|
542
566
|
maxPriorityFeePerGas: priorityFee,
|
|
567
|
+
baseFeePerGas: null,
|
|
543
568
|
};
|
|
544
569
|
}
|
|
545
570
|
const maxFeePerGas = (baseFee * config.baseFeeMultiplierPct) / 100n + priorityFee;
|
|
546
|
-
return {
|
|
571
|
+
return {
|
|
572
|
+
maxFeePerGas,
|
|
573
|
+
maxPriorityFeePerGas: priorityFee,
|
|
574
|
+
baseFeePerGas: baseFee,
|
|
575
|
+
};
|
|
547
576
|
}
|
|
548
577
|
// Nearest-rank percentile over a bigint sample. Empty sample → 0n.
|
|
549
578
|
function percentileBigInt(values, percentile) {
|