Skip to content

feat!: no_from#21716

Merged
Thunkar merged 28 commits intomerge-train/fairiesfrom
gj/no_from
Mar 18, 2026
Merged

feat!: no_from#21716
Thunkar merged 28 commits intomerge-train/fairiesfrom
gj/no_from

Conversation

@Thunkar
Copy link
Contributor

@Thunkar Thunkar commented Mar 18, 2026

Getting rid of the tyranny of the Account entrypoint, and the terrible sentinel value of AztecAddress.ZERO in the from parameter.

Now, when a tx is specified as being sent from: NO_FROM, the wallet completely bypasses the account contract. It doesn't even use the MulticallEntrypoint contract, it'll just execute a single call using DefaultEntrypoint. Since we can do wrapping at the app level, this means ANYTHING goes. Want to wrap 10 calls on a special sauce multicall? Go ahead. App-sponsored FPC with custom logic that must be the first on the chain? Knock yourself out!

Even better news: this is thoroughly tested in our codebase thanks to account contract self-deployments. They're a great example of "I don't want to use an account contract as entrypoint" flow.

As an extra side effect, this completely deshrines the MulticallEntrypoint protocol contract from the wallet (we only have the convenience now of it being already registered in every single wallet)

@Thunkar Thunkar added the ci-draft Run CI on draft PRs. label Mar 18, 2026
@Thunkar Thunkar added the ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure label Mar 18, 2026
@Thunkar Thunkar marked this pull request as ready for review March 18, 2026 09:00
@Thunkar Thunkar requested review from a team and nventuro as code owners March 18, 2026 09:00
@Thunkar Thunkar requested review from mverzilli and nchamo March 18, 2026 09:48

const deployOpts: DeployAccountOptions<InteractionWaitOptions> = {
from: AztecAddress.ZERO,
from: NO_FROM,
Copy link
Contributor

Choose a reason for hiding this comment

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

NO_FROM sounds so strange, isn't there some other way to name this hinting at its effects? maybe something like PAYLOAD_DEFINED_FROM (which is probably wronger and horribler, but I'm trying to convey my objection)

Copy link
Contributor

Choose a reason for hiding this comment

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

seeing the changes to the docs, maybe CREATED_BY_TX

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not in love with the naming too, I went for parallelism with NO_WAIT...

Copy link
Contributor

Choose a reason for hiding this comment

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

It is weird, yes, but I'm also having trouble coming up with something better. Perhaps from: DIRECT_CALL? idk

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that NO_FROM sounds strange. Now that Claude is back up, it suggested a few options:

  • DIRECT or DIRECT_EXECUTION -- signals that the tx bypasses the account contract entrypoint
  • NO_ACCOUNT -- clearer that you're opting out of account contract wrapping
  • RAW -- short, implies no wrapping/mediation
  • SELF -- the transaction acts on its own behalf without an intermediary account contract
  • UNMEDIATED -- explicitly says "no account contract mediation"
  • ENTRYPOINTLESS -- describes the mechanism being skipped (the account entrypoint)
  • NO_SENDER -- closer to the domain: there's no "sender" account wrapping the call

And it even provided a ranking 😅

My ranking would be: DIRECT > NO_ACCOUNT > NO_SENDER > SELF > UNMEDIATED > ENTRYPOINTLESS > RAW > NO_FROM.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry but all of those are worse IMO xD

from is pretty generic, it has no concept of account (wallet just happens to make it so from is an account, but we had the exception of the multicall entrypoint...which is not one). The NO_WAIT parallel is also a pro in my book

Comment on lines +229 to +257
let overrides: SimulationOverrides | undefined;
let txRequest: TxExecutionRequest;
if (from === NO_FROM) {
const entrypoint = new DefaultEntrypoint();
txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
} else {
const useOverride = this.simulationMode === 'kernelless-override';
let fromAccount: Account;
if (useOverride) {
const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
fromAccount = account;
overrides = {
contracts: { [from.toString()]: { instance, artifact } },
};
} else {
fromAccount = await this.getAccountFromAddress(from);
}
const executionOptions: DefaultAccountEntrypointOptions = {
txNonce: Fr.random(),
cancellable: this.cancellableTransactions,
feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions,
};
txRequest = await fromAccount.createTxExecutionRequest(
finalExecutionPayload,
feeOptions.gasSettings,
chainInfo,
executionOptions,
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: extract this to an aux function that gives you { txRequest, overrides } so we can use early returns and avoid the fat else branch

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since this is in itself a helper, I didn't want to muddy the waters further...I think it conveys "bare entrypoint vs. account contract well". But maybe I'm just too brain damaged by now

Copy link
Contributor

@mverzilli mverzilli left a comment

Choose a reason for hiding this comment

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

This makes a ton of sense and the implementation looks solid, my only concern is with NO_FROM naming given it's gonna be public API. I don't have a strong enough alternative I can propose so approving, maybe I would run this through people with a less close perspective of the codebase (eg devrel, Wonder, Ciara, etc)


const deployOpts: DeployAccountOptions<InteractionWaitOptions> = {
from: AztecAddress.ZERO,
from: NO_FROM,
Copy link
Contributor

Choose a reason for hiding this comment

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

It is weird, yes, but I'm also having trouble coming up with something better. Perhaps from: DIRECT_CALL? idk

Comment on lines +17 to +19
console.error(
"data.json not found. Run 'yarn data' first to generate proof data.",
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is your formatter configured to fewer than 120 chars?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the doc examples are...weird. I cannot get the ts server to behave with them and editing them does whatever. They also take forever to build...we have to talk to devrel about this

Comment on lines +163 to +164
// Account contracts are always universally deployed (deployer = ZERO),
// but we still need to know the original `from` to detect self-deployment.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are they always universally deplyoed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Convention. Nothing prevents us from doing it differently

Copy link
Contributor

@nchamo nchamo left a comment

Choose a reason for hiding this comment

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

Great work!

@Thunkar Thunkar merged commit 2257864 into merge-train/fairies Mar 18, 2026
11 checks passed
@Thunkar Thunkar deleted the gj/no_from branch March 18, 2026 20:53
@AztecBot
Copy link
Collaborator

❌ Failed to cherry-pick to v4-next due to conflicts. (🤖) View backport run.

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

Labels

backport-to-v4-next ci-draft Run CI on draft PRs. ci-no-fail-fast Sets NO_FAIL_FAST in the CI so the run is not aborted on the first failure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants