I first came across this EIP earlier this year while looking at Ethereum’s roadmap (https://strawmap.org/), where the Hetoga upgrade had “Native AA” listed. That immediately caught my attention — account abstraction, something that had been talked about for so long, was suddenly going live! But about a week later, the block that originally said “Native AA” was changed to “frame transaction”.
Over the past few years, Account Abstraction (AA) has been a constant focus — from the earliest EIP-86, to the widely deployed ERC-4337, to the EOA delegation scheme of EIP-3074, and finally to the elegant EIP-7702. Each of these solutions has been a workaround layered on top of the existing EOA / contract architecture, because achieving native account abstraction (Native AA) requires changes to the protocol itself — a massive undertaking. But years of upgrades have given the execution layer more capabilities and greater flexibility for different transaction types (such as EIP-2718), and with the looming threat from quantum computing, we’ve finally reached the endpoint of this evolutionary path — EIP-8141 Frame Transaction.
ERC-4337 was the first solution to see large-scale adoption. It took a pragmatic route — leaving the protocol layer untouched and building an entire layer of scaffolding on top. It introduced a separate mempool and a “Bundler” network: users package their operations as a UserOperation, and the bundler collects and verifies these operations before batching them on-chain as a single ordinary EOA transaction. This architecture made features like multisig wallets, social recovery, and passkey login much easier to implement and more widely available, and the burden on contract wallet developers was much lighter — they no longer had to build the infrastructure themselves. But the infrastructure itself is still heavy: developing bundlers and paymasters is time-consuming, maintaining them is costly, and ultimately, users have to rely on services from large providers.
EIP-7702 is an elegant transitional step that lets an EOA “borrow” a smart contract’s code to execute at its own address, without changing the fundamental nature of the account. As a result, existing EOAs can enjoy batch transactions, gas sponsorship, and other benefits without migrating to a new address. Without the quantum threat, this solution would be enough to cover most current AA needs. But since transactions remain EOA at their core, the underlying ECDSA keypair still faces the quantum threat.
EIP-8141 is the endpoint of this evolution. It modifies Ethereum’s underlying architecture directly, introducing a brand new transaction type — Frame Transaction. The protocol natively replaces the role of bundlers, ECDSA signatures are no longer the only credential for an account, and post-quantum cryptography is formally introduced into the system for the first time.
This article starts with the core architecture of Frame Transaction, then walks through its execution modes, authorization mechanism, and gas accounting. Finally, a concrete example shows how it changes everyday on-chain interactions.
To understand why Frame Transaction looks the way it does, we first need to see how traditional transactions are structured.
A traditional EOA transaction has this structure: from (who is acting), to (where to execute), data (what to do). This structure compresses three things — "who is acting", "what to execute", and "who pays" — into a single transaction, and all three are controlled by the same private key. This is fine in the simplest cases. But once you need to separate them — say, letting someone else pay your gas, or doing several things in one transaction — it starts to break down.
EIP-8141’s design choice is to go back to fundamentals: split “verification”, “execution”, and “payment” into separate frames, each with its own role, defined directly by the protocol. A Frame Transaction can contain an array of frames — currently up to 64. Each frame can be thought of as an independent sub-transaction — similar to how a MultiCall contract executes multiple calls in one go. The fields of a Frame Transaction are defined as follows:
[chain_id, nonce, sender, frames, max_priority_fee_per_gas, max_fee_per_gas, max_fee_per_blob_gas, blob_versioned_hashes]frames = [
[mode, flags, target, gas_limit, value, data],
[mode, flags, target, gas_limit, value, data],
…
]
The transaction type code is FRAME_TX_TYPE = 0x06. Within the overall structure, the parts worth paying attention to are sender and frames — the rest is similar to a regular transaction.
# Before we start: clarifying what “address” means #
Before diving into the details, I want to clarify what each “address” represents, to avoid mixing up the roles.
As shown on Etherscan, looking at From and To:
Now, from the contract’s perspective:
But there’s an important change: the semantics of the ORIGIN opcode are redefined as "the caller of the current frame", no longer the traditional "EOA that initiated the entire transaction". So the value also differs across modes:
This is a change that affects contract implementations. Any contract that relies on tx.origin == msg.sender to check "is this a direct EOA call" will be affected. Under EIP-8141, tx.sender itself can be a contract account, and this check can no longer distinguish "EOA-initiated" from "contract-account-initiated".
# Other new structural details #
Dedicated flags field: A control flag field used to configure special behaviors for the frame. Bits 0 and 1 set the approval scope, and bit 2 (value 0x04) sets atomic batch. Approval scope and atomic batch are covered in more detail later.
Native value field: The initial version didn't have this field — it was added after community feedback. With this field, a frame can support ETH transfers, but there's an important restriction: only SENDER mode frames can carry a non-zero value. ETH can now be transferred directly within a SENDER frame, so contract accounts no longer need to implement complex ETH-handling logic themselves — significantly reducing the burden on developers.
Default target: Each frame has its own target. If it's null, it defaults to tx.sender.
Receipt structure changes: Since a Frame Transaction doesn’t have to be paid by the transaction sender (a paymaster can sponsor it), and the payer can’t be statically inferred from the transaction, EIP-8141 explicitly adds a payer field to the receipt.
Each frame also has its own sub-receipt recording execution status (success/failure), actual gas used, and emitted logs. This allows block explorers to clearly display the result of each frame.
A frame transaction has three modes, corresponding to three different roles and trust boundaries in account abstraction.
# VERIFY mode: read-only validation #
This mode is for verifying signatures and confirming the validity of the transaction. It cannot write any state — like STATICCALL, it can only read and compute. The design here is conceptually the same as ERC-4337: during the validation phase, state cannot be modified and external dynamic information cannot be read — preventing cases where off-chain simulation succeeds but on-chain execution fails. After validation succeeds, you need to call APPROVE to set payer_approved or sender_approved.
Background: How does sig_hash work in a traditional transaction?
Before getting into why VERIFY frame’s data has these particular design choices, we need to understand how Ethereum handles transaction signatures at the lower level. We don't sign a raw data blob (like the entire transaction content) directly. Instead, we follow these three steps:
In the traditional transaction structure, v, r, s are three separate fields. When computing sig_hash, these three fields are left blank — the hash is computed, the transaction is signed, and then the values are filled in. In a traditional transaction, "the data being signed" and "where the signature is stored (v, r, s)" are kept separate.
In EIP-8141, however, the protocol no longer hard-codes fixed v, r, s fields. This is to support arbitrary signature verification logic — multisig, passkey, or future post-quantum schemes. All signature data and sponsor authorization credentials must now be packed as parameters into the VERIFY frame's data field, for the contract to parse. Because the signature now lives inside data, the field is automatically omitted when computing sig_hash. There are three reasons for this:
This brings an important security implication: the user’s signature does not cover data, so the contents of data can be tampered with. Charging parameters like exchange rates and fee caps can't be supplied by the user through data. The paymaster needs to provide and sign these itself, so the on-chain contract can verify them and prevent tampering.
# SENDER mode: executing as the user #
This mode is just a regular contract call, with the caller being tx.sender. When any contract is called, the target contract sees msg.sender as the user's address. This is the key to backwards compatibility: contracts like Uniswap and Aave don't need to know frame transaction exists at all.
But SENDER mode has a strict prerequisite: by the time the frame is executed, sender_approved must already be true, otherwise the entire transaction is invalid. This constraint prevents an obvious impersonation attack: without this rule, anyone could construct a frame transaction with an arbitrary address in tx.sender, and use a SENDER frame to impersonate that address when calling contracts. The mandatory order of VERIFY first (authenticate sender identity via signature), then SENDER (execute as the sender) ensures that execution must rest on an explicit authorization.
# DEFAULT mode: the protocol’s neutral executor #
This mode is also a regular contract call, but the caller is ENTRY_POINT (address(0xaa)) — a virtual address defined by the protocol, not a deployed contract. It exists to provide a neutral execution identity for operations that aren't the user and shouldn't have any self-interest of their own. The two typical uses are:
Here is the simple table to summarize the three modes.
Summary of three modesHow this differs from ERC-4337’s EntryPoint
Now that we’ve covered the three modes, APPROVE is the key that ties them together.
First, a definition: resolved_target is frame.target if set, otherwise tx.sender.
APPROVE has a scope parameter (bits 0 and 1 of frame.flags), which determines what's being authorized in this call:
EIP-8141 separates the roles of user and sponsor (similar to ERC-4337’s paymaster design), so authorization is split accordingly. At the end of verification, the APPROVE opcode sets the authorization state for both roles. Its behavior is similar to RETURN — it successfully terminates the current frame's execution. Additionally, payer_approved and sender_approved are global across the transaction and cannot be set repeatedly — setting one to true when it's already true will revert.
If the sponsor’s balance is insufficient, the entire frame reverts. After all frames finish executing, any unused gas is refunded to the sponsor. This is a “pre-charge, then refund” approach, consistent with how traditional transactions deduct gas_limit × gas_price upfront and refund the difference afterward.
Similarly, APPROVE(APPROVE_PAYMENT_AND_EXECUTION) does all of the above and also sets sender_approved = true.
# Execution order constraint #
Authorization has a strict order: sender_approved = true must be set first to confirm the user's identity, before the paymaster can be authorized to set payer_approved = true. Otherwise the transaction reverts. Furthermore, setting payer_approved triggers three actions at the same time:
Why this order matters:
# Caller constraint #
There’s a restriction when calling APPROVE: the address executing APPROVE must itself be the frame’s target execution address — i.e., ADDRESS == resolved_target. Otherwise it reverts. In other words, you can't set frame.target to contract A and then use STATICCALL into contract B to call APPROVE from there. This prevents accidentally triggering APPROVE in a malicious contract that grants authorizations on your behalf. But DELEGATECALL is fine — it stays in the caller's context, so ADDRESS is still the target itself.
To summarize so far, the flow of a Frame Transaction looks roughly like this:
Frame Transaction FlowThe next question is how this design integrates with the current execution layer — and what to do about EOA users.
The core architecture of Frame Transaction is complete and elegant for smart contract accounts, but there’s a practical issue: the vast majority of users on Ethereum today are EOAs, with no contracts deployed at their addresses. If Frame Transaction required the target address to have a contract for signature verification, every EOA user would have to deploy an account contract before using the new features — a huge migration cost.
EIP-8141 solves this with “Default Code”. When a user has neither a contract nor an EIP-7702 delegation, the protocol doesn’t reject the call. Instead, it executes a piece of logic predefined at the protocol layer — as if the address had invisibly deployed a standard “mini verification contract”.
The key point about default code: EOAs don’t need to deploy any contracts or migrate assets to a new address to enjoy all the benefits of Frame Transaction — gas sponsorship, batch operations, paying gas in ERC-20, passkey login, and so on. For EOA users, the only difference is that their wallet provider needs to support Frame Transaction.
Top-level logic of default code# DEFAULT branch: revert directly #
An EOA’s default code doesn’t support DEFAULT mode. A DEFAULT frame’s caller is ENTRY_POINT, typically used for paymaster post-ops — not a scenario an EOA would trigger.
# VERIFYbranch: signature type determined by data#
The first byte:
Default code natively supports P256 — the signature scheme behind today’s most popular passkey. When a user creates a passkey on their phone, the Secure Enclave automatically generates a P256 keypair, allowing the passkey public/private keys to derive an address directly. From that point on, the only credential for this account is the P256 private key stored in hardware — no seed phrase needed at all.
Diagram 2: Default code VERIFY branch logicIt’s worth noting that EIP-8141 itself doesn’t directly introduce post-quantum (PQ) secure signature schemes. The real PQ significance of EIP-8141 is: the VERIFY frame can execute arbitrary EVM code for signature verification. Today it can be secp256k1 or P256; tomorrow it can be Dilithium or Falcon or other PQ schemes. When PQ signature precompiled contracts are introduced in the future, contract accounts only need to update their own verification logic — no protocol upgrade required. This is what the spec calls a “native off-ramp from ECDSA”: handing the power to choose the signature scheme from the protocol down to the account.
# SENDER branch: batch operations for EOAs #
For an EOA, a SENDER frame is more than just “transferring”. frame.data is an RLP-encoded call list [[target, value, data], …], allowing multiple calls to be executed in sequence within a single frame. As a result, EOAs can do batch operations (such as approve + swap in one go) without deploying any contracts.
Diagram 3: Default code SENDER branch logicTraditional EVM contracts can only see information about “the current call”: CALLDATA, CALLER, CALLVALUE. In a frame transaction, the contract in each frame may need a wider view. The paymaster needs to know the maximum fee for the entire transaction, the verification contract needs to get the sig_hash, and post-quantum schemes need to efficiently load 2KB+ of signature data. EIP-8141 introduces several new opcodes. In addition to APPROVE covered above, there are also TXPARAM, FRAMEDATALOAD, FRAMEDATACOPY, and FRAMEPARAM.
# TXPARAM (0xb0) / FRAMEPARAM (0xb3): reading transaction- and frame-level information #
These two opcodes give contracts powerful introspection capabilities:
This lets a contract read other frames. For example, a post-op DEFAULT frame can use FRAMEPARAM to check whether the third SENDER frame executed successfully and decide whether to issue a refund. TXPARAM's ability to directly read the cached sig_hash saves the enormous gas cost of manually RLP-encoding within the EVM, making it the single most important opcode for implementing verification contracts.
# FRAMEDATALOAD (0xb1) / FRAMEDATACOPY (0xb2): cross-frame data reading #
These two opcodes mirror the semantics of CALLDATALOAD and CALLDATACOPY, with the difference that you can specify which frame's data to read, not just the current frame. There are two design motivations. First, the paymaster's VERIFY frame needs to read the SENDER frame's data to confirm that the operation the user actually wants to execute matches its payment conditions — for example, to confirm that the SENDER frame's calldata really is transfer(sponsor, N USDC) and not some other unauthorized operation. Second, post-quantum signature data is large — a full CRYSTALS-Dilithium signature is about 2.4KB — and FRAMEDATACOPY can be used to copy a VERIFY frame's own data into memory.
Gas accounting in frame transaction differs fundamentally from traditional transactions in one place: each frame’s gas budget is fixed at transaction construction time and can’t be borrowed across frames.
The gas calculation for a frame transaction:
tx_gas_limit = 15,000 // Fixed base cost (FRAME_TX_INTRINSIC_COST)
+ len(frames) × 475 // Fixed per-frame overhead (FRAME_TX_PER_FRAME_COST)
+ calldata_cost(rlp(frames)) // Calldata cost of frames themselves
+ sum(frame.gas_limit for all frames) // Sum of each frame's execution budget
The 475 gas fixed overhead per frame breaks down into two parts: 100 for setting up the CALL execution context, and 375 (the G_log write cost) for each frame producing its own receipt sub-entry ([status, gas_used, logs]). The implication: each frame leaves its own execution record on-chain, and you can clearly see from the receipt which frame succeeded, which frame reverted, and how much gas each one used.
Why must each frame’s gas_limit be independent, with no borrowing between frames? This is a deliberate design decision, so that each frame's gas consumption can be calculated at transaction construction time. The paymaster can then accurately estimate the maximum cost of the entire transaction at the first VERIFY stage (before any SENDER frame has executed), without the fee estimate going off because one frame "accidentally borrows" gas from another.
After all frames finish executing, the refund is calculated uniformly:
This refund goes back to the payer, and the leftover gas is returned to the block’s gas pool.
A frame is conceptually an EVM CALL, but there are some differences in the details. There’s an important difference between a frame and aCALL in how they handle transient storage and warm/cold state. Transient storage is cleared across frames, but warm/cold state is still shared across frames:
Differences between CALL and frame# The meaning of clearing transient storage #
Each frame is an independent execution unit, to keep each frame’s behavior predictable. But there’s a security pitfall to be especially careful of. After EIP-1153, many contracts replaced their SSTORE-based reentrancy guards with TSTORE, because it's much cheaper. Under Frame Transaction, transient storage is cleared between frames. As a result, if both frame 1 and frame 2 of a transaction call the same contract with a transient guard, the two calls will be treated as independent "first calls" and won't trigger the reentrancy guard.
In most contexts this doesn’t constitute a security vulnerability — reentrancy was originally about reentering within the same call stack, and frames are independent call stacks by design. But if a contract’s logic relies on the assumption that “this can only execute once per transaction”, it needs to switch back to SSTORE.
# Warm/cold state shared across frames #
This design is for gas efficiency. If frame 0 has already read a storage slot (making it warm), then frame 1 reading the same slot only pays the warm read cost (100 gas) rather than the cold read cost (2,100 gas). This is consistent with how multiple reads of the same slot work within a traditional transaction — developers don’t need to handle it specially.
The revert semantics of traditional transactions are very simple: any call layer reverts, and the entire transaction rolls back. Frame Transaction breaks this default, leaving the revert boundary up to the developer to decide.
Default: independent frames
If you do nothing, each SENDER frame’s revert only affects itself. If frame 2 reverts, frame 2’s state changes are discarded, and frame 3 still executes as usual. The entire transaction still goes on-chain. This behavior is useful for certain scenarios — for example, ‘try multiple routes, succeed if any one works’, or post-op refunds that shouldn’t roll back the entire user operation just because of some edge case
Opt-in: atomic batch
When you need multiple operations bundled as all-or-nothing, you can set bit 2 of the flags field on a SENDER frame. A consecutive run of SENDER frames with this flag set, plus the first SENDER frame after them that doesn't have this flag, together form an atomic group.
How an atomic batch executes:
For example, suppose group A is frames 0 and 1, and group B is frames 2, 3, and 4. If frame 3 reverts, the state of group B (frames 2, 3, 4) is fully rolled back, but the results of group A are completely unaffected. This design allows multiple independent atomic groups to exist within a single transaction.
Frame revert in an atomic batchERC-4337’s bundler architecture is cumbersome, but it has a hidden benefit: the bundler is a party with skin in the game — it won’t accept transactions that make it lose money, so it’s incentivized to strictly filter problematic UserOperations. The DoS risk of verification logic is borne by the bundler, and never reaches the nodes.
Frame Transaction goes directly into the public mempool, and this protective layer disappears. Nodes now have to execute arbitrary VERIFY contract code themselves to determine whether a transaction is valid. This immediately opens up an attack vector: an attacker can craft a transaction whose verification logic “looks legitimate but is expensive to execute” and submit it to the mempool, forcing the node to waste compute on it.
Even more dangerous is the mass invalidation attack. If the validity of a thousand pending transactions all depends on the same storage slot (such as a paymaster’s balance), an attacker only needs to send one transaction to zero out that slot, and all thousand transactions become invalid at once — meaning the node validated them a thousand times for nothing.
To address this, EIP-8141 introduces the concept of a validation prefix. Before entering the public mempool, a transaction must pass the validation prefix rules, which only allow a small set of behaviors.
What nodes actually need to protect against is “all execution that happens before fee payment is confirmed”, because that’s the part the node executes for free. If this part can be abused, it becomes a DoS vector. Once payer_approved == true, the node has confirmed that someone will pay, and subsequent execution can be arbitrarily complex — the miner is compensated for the work.
Definition of validation prefix: the shortest prefix of frames whose successful execution sets payer_approved = true.
Once payer_approved is set to true at the end of a frame, that frame is the last frame of the validation prefix. Subsequent frames (like user_op, post_op) fall outside the validation prefix and aren't subject to the mempool's protection rules.
In short: once a sponsor is found and payment is confirmed, subsequent frames follow the same rules as ordinary transactions. To avoid burning too much compute before finding the sponsor, we want this prefix to be as short as possible. Currently only the following four scenarios are supported:
Excluding contract deployment, these scenarios only set one of two flags: payer_approved = true or sender_approved = true. Additionally, the total gas cap of the validation prefix is MAX_VERIFY_GAS = 100,000. This caps the simulation cost for nodes — even if an attacker designs verification logic that burns a lot of gas, the most they can waste is 100k gas per transaction.
# Front-running risk of the deploy frame #
One important caveat: the deploy frame happens before any verification, when tx.sender hasn't been authenticated yet. Anyone can therefore front-run the deployment to tx.sender using the same deterministic factory, initcode, and salt. For this reason, EIP-8141's security guidelines specify:
As the table above shows, the validation prefix is essentially the prerequisite setup before the transaction starts (deploy, pay) or verification (self_verify, only_verify).
Going back to the VERIFY frame section above, anything that “depends on environmental state” is forbidden. If verification logic uses TIMESTAMP, a transaction that validated yesterday could fail today because the timestamp passed some deadline. An attacker could flood the mempool with such transactions just before a deadline, and once the time passes, all of them become invalid — wasting node compute. The same applies to BLOCKHASH, NUMBER, COINBASE, ORIGIN, and other environment-related opcodes.
BALANCE and SELFBALANCE: If the paymaster's verification logic reads its own ETH balance, then any transaction that changes the paymaster's balance (including ordinary transfers) could simultaneously invalidate a large number of pending transactions, so it can't be relied on for verification.
SLOAD is allowed, but only for reading tx.sender's own storage — not the storage of any other address (including any address reached through CALL or DELEGATECALL), because external storage can change at any time.
SSTORE, TLOAD, and TSTORE are completely forbidden in the validation prefix. The validation stage can't write any state, the same as STATICCALL. This applies not just to the VERIFY frame — the entire prefix is treated as read-only during node simulation.
We just said the pay frame can’t read the paymaster’s own storage — so how does the paymaster confirm it has enough ETH to cover the gas? This contradiction is one of the most interesting parts of the mempool design. EIP-8141’s solution is to split paymasters into two categories, each solving this problem with a different mechanism:
Canonical Paymaster: the node keeps the books
A canonical paymaster is a protocol-standard implementation that anyone can deploy, but the pay frame’s runtime code must match the protocol specification exactly. When the node recognizes a canonical paymaster, the validation prefix rules don’t apply to the pay frame. Instead, the node maintains a local ledger:
available_balance = state.balance(paymaster)
- reserved_pending_cost(paymaster) // Fees reserved for other pending transactions
- pending_withdrawal_amount(paymaster) // Amount in withdrawal (with lock-up period)
Only transactions where available_balance >= tx_max_cost are accepted into the mempool. For each accepted transaction, reserved_pending_cost increases by that transaction's max cost; when the transaction is included on-chain or evicted, the reservation is released. This ledger is local to the node and never goes on-chain, but it's enough to prevent the paymaster from over-committing. This design lets a canonical paymaster sponsor gas for an unlimited number of accounts, making it the right tool for dApps and wallet providers offering "gasless experiences" at scale.
Non-canonical Paymaster: flexibility at the cost of quantity limits
Any contract that doesn’t conform to the canonical paymaster spec is treated as a non-canonical paymaster. The node can’t maintain a balance ledger for it, since the paymaster’s withdrawal logic is unknown. Instead, it applies a blunt but effective rule: each non-canonical paymaster can have at most one pending transaction in the public mempool.
This restriction ensures that even if a non-canonical paymaster’s balance suddenly drops to zero, at most one transaction is affected, and mass invalidation is impossible.
The main use case for the non-canonical paymaster is the “gas account” pattern: the user’s everyday account doesn’t need to hold ETH — every transaction pays gas fees with stablecoins like USDC, while a separate EOA dedicated to holding ETH covers the gas. Since every EOA supports default code, this gas account doesn’t need to deploy any contract to act as a paymaster. Its default code verifies the ECDSA signature directly in the VERIFY frame and calls APPROVE(APPROVE_PAYMENT) — no extra infrastructure needed. The only restriction is that this "gas account" can have at most one transaction waiting in the mempool at any given time, but for personal use cases that's more than enough.
By now we have all the pieces to understand Frame Transaction. Let’s assemble them with a concrete scenario — the focus isn’t just “what is a frame”, but “why each frame is designed this way”.
The user’s wallet only has USDC, no ETH, and wants to complete a swap on Uniswap. Under ERC-4337, this required off-chain coordination between the bundler and the paymaster. Under EIP-8141, this is packaged into a single Frame Transaction:
From the early days of EIP-86, through ERC-4337’s architecture, to EIP-7702’s elegant transition — Ethereum’s native account abstraction is drawing ever closer.
For contract developers, EIP-8141 cuts both ways. The good news is that existing contracts hardly need any changes — Frame Transaction’s SENDER frame keeps msg.sender as the user's address, so Uniswap and Aave don't need to know anything has changed. The bad news is that some long-standing security assumptions need to be reexamined:
For account infrastructure developers (wallets, paymaster service providers), EIP-8141 is an opportunity to migrate from ERC-4337’s application-layer approach to protocol-native support. It also brings new engineering challenges: canonical paymaster version management, deploy frame retry logic, and cross-chain account consistency.
EIP-8141 has been moving fast: officially proposed as a draft on January 29, 2026, with EOA default code support added on March 5. At the ACDE meeting on March 26, the proposal received “Considered for Inclusion” (CFI) status and is planned to be included in the Hegota upgrade, which is expected to start in the second half of 2026. Major clients (Geth, Erigon, Nimbus) are voicing support, but the core developer team still has concerns — questions remain around mempool stability, transaction encoding complexity, and other details. Looking forward to seeing it ship in the Hegota upgrade!
Native Account Abstraction — EIP-8141 Frame Transaction was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.


