feat(standards): add the pass-through auth component - #3733
Draft
mmagician wants to merge 8 commits into
Draft
Conversation
`AuthPassThrough` asserts the account's commitment is the one the transaction started with, never increments the nonce, and pays no transaction fee. That is what makes a pass-through account immutable: nothing can alter it, so transactions against it never conflict and batches can be built concurrently. With `NoAuth` any third party could mutate the account, and on a fee-charging chain it funded a TX_FEE note out of the account's vault - the "skipping fee note creation" half of #3709. With the invariant enforced by the auth procedure, the script's own `assert_vault_unchanged` call becomes redundant and is removed, leaving the action component with a single procedure; it is renamed `PassThroughSweep` (`miden::standards::pass_through::sweep`) so the other actions a pass-through script might call have somewhere to land. Registers both components with `StandardAccountComponent` and `AccountComponentInterface`. Without the auth variant `AccountInterface::new` finds no auth component and panics on any pass-through account. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
The script's MASM contract promised a vault-unchanged guarantee it delegated to the auth procedure and cannot verify. Says so, and spells out the two silent failure modes on an account composed differently. Also corrects the fee claim: a FEE_SPONSORSHIP note could in principle fund a fee note, so the accurate statement is that this procedure creates none. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
The auth procedure asserts a zero net vault delta, not the absence of withdrawals, so "an account that cannot change its state cannot fund a fee note" does not follow: another script could route assets an input note deposited into a TX_FEE note of its own and still pass the assert. Scopes the claim to what the procedure and the canonical script actually guarantee. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
Third copy of the claim the previous commit corrected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
Rebase fallout: the sweep component is down to one procedure, so its export test shrinks with it, and the root-stability check needs the renamed component plus the new auth one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
`sweep_asset_to_note_root` resolves a hand-written path through a `LazyLock` that panics on a mismatch, and nothing forced it, so a typo would have surfaced in a downstream caller rather than in CI. Folds the check into the interface test that already builds a pass-through account. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
The MASM doc lost the paragraph the Rust one still carried and was left with a dangling fragment on the requires list; the component doc had a sentence clippy read as a list continuation, and one link still pointed at the old component name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
Adds an `Auth::PassThrough` testing variant and a test asserting an account-creating transaction fails with `ERR_EPILOGUE_NONCE_CANNOT_BE_0`, so the documented limitation is covered rather than only asserted in prose. Also drops a stale sentence claiming a pre-existing balance is swept out along with the deposits; `sweep_asset_to_note` asserts against that and fails the transaction instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB
This was referenced Aug 25, 2026
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.
Stacked on #3713 - review that first; this diff is only the auth component and what follows from it.
Closes the second half of #3709, "skipping fee note creation".
What it does
AuthPassThroughasserts the account's commitment is the one the transaction started with, never increments the nonce, and creates noTX_FEEnote. That is what makes a pass-through account immutable: nothing can alter it, so transactions against it never conflict and a batch builder can append one to every batch it builds concurrently.With
NoAuthneither property held. Any third party could run a transaction against the account and change its state, breaking the concurrency guarantee independently of the script; and on a fee-charging chain the auth procedure funded aTX_FEEnote out of the account's vault, which is both a state change and impossible for an account the script has just emptied.What follows from it
assert_vault_unchangedis removed. The auth procedure's commitment check subsumes it - it runs after the tx script and also covers storage - so the script's own call became redundant. The script's docs say plainly that the guarantee is a property of the account composition, which the script cannot verify.PassThroughSweep(miden::standards::pass_through::sweep), since it is down to a single procedure and other pass-through actions need somewhere to land.StandardAccountComponentandAccountComponentInterface. Without the auth variant,AccountInterface::newfinds no auth component and panics -AccountInterface::from_accountwould have been a panic on valid input.Worth reviewing
TX_FEEnotes are the latter, which is why fee forwarding is sound while routing a P2ID note through such an account would not be.pass_through_auth_cannot_create_an_account.Testing
Three tests in
crates/miden-testing/tests/auth/pass_through.rs: a transaction leaving a deposit in the account is rejected, an account-creating transaction fails on the nonce, and on a chain with a non-zeroverification_base_feethe only output is the P2ID note with the account unchanged. Plus an interface test pinning the component registration that would otherwise panic. The existing script tests move over toAuthPassThrough.make lintandmake docclean;miden-standardsandmiden-testinggreen.🤖 Generated with Claude Code
https://claude.ai/code/session_01NyebszMeyUrYBjsJBDLVwB