feat(arbitrum-adapter): implement previewSequencerFee via NodeInterface.gasEstimateComponents#21
Merged
Merged
Conversation
…ce.gasEstimateComponents
Turn the previewSequencerFee skeleton (returned null) into a live estimation.
- Reads NodeInterface.gasEstimateComponents (precompile 0xC8) through a
caller-supplied viem PublicClient. The precompile simulates the (to, data)
call and returns gasEstimate, gasEstimateForL1, baseFee (L2), and
l1BaseFeeEstimate. We mark the ABI `view` so viem readContract accepts the
canonically-payable method; eth_call ignores declared mutability. Verified
live against Arbitrum One mainnet.
- Fee math (Arbitrum Nitro): both components priced at the L2 base fee.
l1FeeWei = gasEstimateForL1 * baseFee; l2FeeWei = (gasEstimate -
gasEstimateForL1) * baseFee; totalFeeWei = gasEstimate * baseFee. Fills
every SequencerFeePreview field.
- Signature is now async (client, { chain, to, calldata, from?, l1BaseFeeWei? })
with a required `to` (the precompile needs a destination to simulate) and
the client injected so the function stays RPC-agnostic and testable. Any
failure (RPC down, simulated call reverts, malformed calldata) returns null;
the preview is advisory and must never block signing.
- Rename private isNova -> checkIsNova (predicate-function naming rule).
- Add viem as a peer dependency (>=2); externalized by tsup, not bundled.
- Replace the single stub test with 6 cases over a mock PublicClient: field
math, correct precompile address/function/args, Nova compression flag,
l1BaseFeeWei override, null-on-failure, calldata byte counting.
Untouched: attachSequencerFeePreview, isSequencerFeePreview,
extractSequencerFeePreview, and the bridge / retryable / decoder helpers.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Turns the
previewSequencerFeeskeleton (which returnednull) into a live sequencer-fee estimation. This is the alpha.1 hardening the README flagged ("helper bodies harden in alpha.1 with viem"). Scope: ONE function body + its tests + deps/docs. The pure helpers (attachSequencerFeePreview,isSequencerFeePreview,extractSequencerFeePreview) and the bridge / retryable / decoder modules are untouched.How it works
previewSequencerFee(client, { chain, to, calldata, from?, l1BaseFeeWei? })reads NodeInterface.gasEstimateComponents (precompile0xC8) through a caller-supplied viemPublicClient. The precompile simulates the(to, data)call and returns(gasEstimate, gasEstimateForL1, baseFee, l1BaseFeeEstimate).Fee math (Arbitrum Nitro - both components priced at the L2 base fee, the L1 part is denominated in L2 gas units):
l1FeeWei = gasEstimateForL1 * baseFeel2FeeWei = (gasEstimate - gasEstimateForL1) * baseFeetotalFeeWei = gasEstimate * baseFeeEvery
SequencerFeePreviewfield is filled (l2GasEstimate,l1CalldataBytes,l1BaseFeeWei,l1FeeWei,l2FeeWei,totalFeeWei,isCompressed,previewBlock).Decisions
async, takes the viem client as the first arg (RPC-agnostic + testable), and requirestobecause the precompile simulates a call and needs a destination. A calldata-size-only estimate was rejected because it cannot fill the L2 compute fields.gasEstimateComponentsalone returns the L2 base fee and the L1 base-fee estimate, soArbGasInfowould be a redundant read. Confirmed with the maintainer.view-marked ABI. The canonical method ispayable, but we own the ABI and mark itviewso viemreadContractaccepts it; eth_call ignores declared mutability. Validated live against Arbitrum One mainnet before writing the code (readContractreturned[21689n, 523n, 20062000n, 4151436n], a 4-tuple, fee math sane).null. RPC down, simulated call reverts, or malformed calldata all returnnull- the preview is advisory wallet UX and must never block signing (the type was already| null).isNova->checkIsNova(predicate-function naming rule); only referenced inside this file.Verification
6 new tests over a mock
PublicClient: full field math, correct precompile address/function/args, Nova compression flag,l1BaseFeeWeioverride, null-on-failure, calldata byte counting.Deps
viemadded as a peer dependency (>=2, mirrors core/react/tx-decoder) + dev dependency (^2.48.4). tsup externalizes it - the ESM bundle keepsimport { toHex } from 'viem'and does not inline the library.Left for alpha.1
l1CalldataBytesreports the raw byte count, not the post-Brotli/DAC size (the fee itself is still accurate -gasEstimateForL1already accounts for the DAC).ArbGasInfofallback so the L1 portion can still be shown when the simulated call reverts; plus the decoder-registry expansion and a viem custom-transport integration test.Not merging - leaving open for review.