Skip to content

feat: add frame accounts, transaction preparation and account-aware signing - #24

Merged
Ghadi8 merged 3 commits into
JustaLab-co:mainfrom
nikhilkumar1612:main
Sep 21, 2026
Merged

Ghadi8 merged 3 commits into
JustaLab-co:mainfrom
nikhilkumar1612:main

Conversation

@nikhilkumar1612

Copy link
Copy Markdown
Contributor

What this changes

Updates frametx-kit to use the current seven-field EIP-8141 transaction envelope with a scalar nonce. It also introduces FrameAccount, EOA transaction preparation and account-aware signing APIs.

Why

The previous implementation targeted the superseded composed envelope containing EIP-8250 keyed nonces and EIP-8272 recent-root references. The current Ethrex Frames devnet uses a scalar nonce and no recent-root envelope field.

This also adds a higher-level workflow for constructing EOA frame transactions without manually assembling validation frames, execution frames, nonce values, fees, and signatures.

How the new behaviour is pinned

Which oracle covers this change, and why it could actually fail:

  • A published figure, transcribed rather than derived
  • The golden byte vector or sig-hash from ethrex's frame_tx_wire_tests.rs
  • Re-encoding captured chain data and reproducing the transaction hash
  • A live receipt (recovered signer, maxCost, or the gasUsed decomposition)
  • N/A, this change has no wire-format or gas behaviour

The updated scalar-nonce envelope and signature hash are pinned against Ethrex's golden wire vector. The test fails if field ordering, scalar encoding, fee nesting, signature elision, or the resulting transaction bytes change.

The new account helpers are additionally covered by focused tests for nonce retrieval, frame construction, gas-limit mapping, fee preparation, sender matching, and signature recovery.

Load-bearing rules

Did this touch anything under "Rules that are not style preferences" in CONTRIBUTING.md, such as a derived gas constant, a golden vector, a captured fixture, the module import order, or encodeFrameTx validating?

  • No
  • Yes, and the argument for it is below

This intentionally replaces the superseded nine-field composed envelope with the current seven-field Ethrex envelope:

[
  chain_id,
  nonce,
  sender,
  frames,
  signatures,
  fees,
  blob_versioned_hashes,
]

nikhilkumar1612 and others added 2 commits September 18, 2026 21:02
Align the type 0x06 envelope, RPC parsing, and gas accounting with the current EIP-8141 format. Add FrameAccount, EOA preparation and signing helpers, an ETH transfer example, tests, and updated documentation.

BREAKING CHANGE: FrameTransaction now uses a scalar nonce. The EIP-8250 nonceKeys/nonceSeq and EIP-8272 recentRootReferences fields and related APIs have been removed.
feat!: support scalar-nonce frame transactions and EOA accounts
@Ghadi8 Ghadi8 changed the title ft: adding helpers for frame account(viem comaptible), preparing and signing viem txs feat: adding helpers for frame account(viem comaptible), preparing and signing viem txs Sep 21, 2026

@Ghadi8 Ghadi8 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @nikhilkumar1612!

src/rpc.ts reads the frame field as stateLimit. That is what chain 8141 served when test/fixtures/chain/ was captured, but both live chains now serve stateGasLimit — so BigInt(undefined) throws, and getFrameTransaction (src/viem.ts:52, the first example in the README) is unusable against rpc1.frames.ethrex.xyz.

The hermetic suite can't see it: GOLDEN_RPC_JSON is hand-written and uses the same old name, so the fixture and the code agree with each other and disagree with the node.

Reproduce

import { parseRpcFrameTransaction } from './src/rpc.js'

const r = await fetch('https://rpc1.frames.ethrex.xyz', {
  method: 'POST', headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_getTransactionByHash',
    params: ['0x7f1793de1f93d259ef353252da7f70a7e3cea5a2dc132c36092be1e14360f3f6'] }),
})
parseRpcFrameTransaction((await r.json()).result)
// TypeError: Invalid argument type in ToBigInt operation   <- f.stateLimit is undefined

Fix

src/rpc.ts is outside this PR's diff hunks, so GitHub won't let me leave an applyable suggestion there — patch inline:

@@ -22,7 +22,8 @@ export type RpcFrameTransaction = {
     gasLimit: Hex
-    stateLimit: Hex
+    /** The node calls this `stateGasLimit`, not `stateLimit`. */
+    stateGasLimit: Hex
     value: Hex

@@ -112,7 +113,7 @@ export function parseRpcFrameTransaction(json: RpcFrameTransaction): FrameTransa
     target: f.to === null ? null : getAddress(f.to),
-    limits: { execution: BigInt(f.gasLimit), state: BigInt(f.stateLimit) },
+    limits: { execution: BigInt(f.gasLimit), state: BigInt(f.stateGasLimit) },
     value: BigInt(f.value),

GOLDEN_RPC_JSON has an applyable suggestion below.

Please leave test/fixtures/chain/*.json on stateLimit — they are records of what the old node actually served, and only their simulate block is read now.

Evidence that the rest of the envelope work is correct

With only that rename applied, feeding the node's JSON verbatim through this branch across 22 live type-0x6 transactions on chain 81410:

check result
keccak256(encodeFrameTx(parseRpcFrameTransaction(json))) == node hash 22 / 22
decodeFrameTx(encodeFrameTx(tx)) round-trip 22 / 22
empty-msg secp256k1 signatures recovering to their resolved signer 23 / 23
receipt.gasUsed == intrinsic + Sum(frame gasUsed) + Sum(frame stateGasUsed) 5 / 5 exact

So the seven-field envelope, the nested fees, the nested [execution, state] limits and the sig-hash elision are all right against real chain data — this one field name is what stands between the branch and working end to end.

Worth capturing a handful of these as fixtures to replace the retired test/fixtures/chain/ set: an eth_getLogs sweep from block 0 finds them in one call, and that oracle is exactly what would have caught this.

Comment thread test/fixtures/golden.ts Outdated
@Ghadi8 Ghadi8 changed the title feat: adding helpers for frame account(viem comaptible), preparing and signing viem txs feat: add frame accounts, transaction preparation and account-aware signing Sep 21, 2026
@Ghadi8
Ghadi8 merged commit 882b3cd into JustaLab-co:main Sep 21, 2026
5 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants