Native Ephemeral Key Rotation via Frame Transactions

Small update from our side.

Since our original post, the implementation has changed materially: our main implementation of the Ephemeral Keys design, NiceTry, is no longer based on rotating ECDSA signers, but on FORS+C signatures. The repository now treats FORS as the primary signing path, with the old ECDSA and WOTS implementations kept only as legacy/comparison code. More details on these updates can be found in this comment on the original post.

That said, the original AA implementation should still be understood as an ERC-4337 implementation, not as something directly compatible with frame transactions. The core invariant is the same, but the mechanism is different. In the AA version, signer rotation is tied to the validateUserOp / EntryPoint flow. With frame transactions, validation happens in a VERIFY frame, authorization is expressed through APPROVE, and the VERIFY frame itself cannot perform the state-changing rotation. So the old account logic cannot simply be dropped into the frame model unchanged.

We updated the NiceTry repo with a frame-compatible account direction: the frame-transaction-related work is separated into a FrameAccount path designed around the frame transaction model instead of trying to reuse the ERC-4337 UserOperation flow.

The important design point is enforced rotation. The account does not treat the rotation frame as optional metadata or as a convention that wallets are expected to follow. During validation, after checking the FORS signature against the current owner, the account inspects the immediately following frame and requires it to be the rotation frame.

Concretely, the next frame must:

  • be a SENDER frame;
  • target the account itself;
  • send zero value;
  • not be an atomic batch frame;
  • contain calldata exactly matching rotateOwner(address);
  • provide a nonzero next owner.

If any of those checks fail, validation fails and the transaction is not approved.

This gives the frame version the same operational invariant we wanted in the AA version: a transaction cannot be accepted unless signer rotation is already scheduled as the next action. User execution must come after the rotation frame. That matters because if user execution later reverts, the signer has still already been rotated, so future transactions can safely use fresh FORS keys.

One small side effect of this change is that, as of the current EIP-8141 spec state, this kind of account cannot be used as a paymaster, as it would not be able to add the rotation frame for itself to the user’s transaction.