Skip to content

feat: #[immutables] macro, initializerless account, v4 upgrade with tests and benchmarks#9

Merged
zkfrov merged 42 commits into
feat/constant-accountfrom
test/js
Feb 27, 2026
Merged

feat: #[immutables] macro, initializerless account, v4 upgrade with tests and benchmarks#9
zkfrov merged 42 commits into
feat/constant-accountfrom
test/js

Conversation

@zkfrov
Copy link
Copy Markdown
Collaborator

@zkfrov zkfrov commented Feb 6, 2026

🤖 Linear

Closes AZT-707

  • Add comprehensive TypeScript test suite (E2E, unit, integration) for the #[immutables] macro pattern

    • Add TypeScript utilities for deploying contracts with immutables (salt computation, capsule creation, PXE registration)
    • Add SchnorrInitializerlessAccountContract TypeScript integration (AccountContract impl, AuthWitnessProvider, wallet registration)
    • Add standard SchnorrAccount utilities for comparison testing
    • Add CI workflow for building aztec-standards artifacts
    • Remove duplicate Noir contracts (initializerless/, schnorr_immutables_account_contract/) consolidated in feat/constant-account
    • Update README with TypeScript utilities docs, published vs unpublished deployment, and #[noinitcheck] explanation

    Details

    TypeScript Utilities (src/ts/immutables/utils.ts)

    Generic module for deploying any contract using the #[immutables] macro:

    • computeContractSalt(actualSalt, serializedImmutables) — derives salt via poseidon2Hash
    • createImmutablesCapsule(address, actualSalt, fields) — creates capsule for function calls
    • deployWithImmutables(wallet, artifact, fields, options?) — full deployment: instance creation, PXE registration, class + instance publication
    • Supports both published (on-chain) and unpublished (PXE-only) deployment via skipInstancePublication

    Account Contract Integration (src/ts/schnorr-initializerless-account/)

    • SchnorrInitializerlessAccountContract — implements AccountContract interface (no initializer, salt-based key verification)
    • SchnorrInitializerlessAuthWitnessProvider — Schnorr signature creation for tx authorization
    • registerInitializerlessAccount(wallet, options?) — one-call deployment + wallet registration with key derivation
    • computeSchnorrAccountAddress(signingKey, options?) — pre-compute address before deployment

    Tests

    File Description Tests
    schnorr-initializerless-account.test.ts Immutables pattern for account contracts 12 tests: deploy + read key, different keys/salts → different addresses, wrong capsule/actualSalt rejection, published +
    unpublished variants
    immutables-contract.test.ts Immutables + storage coexistence Published/unpublished deploy, wrong capsule rejection, mixed usage with initializer
    e2e.test.ts End-to-end with Dripper FPC Initializerless account receives private tokens via drip, transfers, balance checks — compared against standard SchnorrAccount

    CI

    • scripts/build-aztec-standards.ts — builds external aztec-standards token/dripper artifacts needed for E2E tests
    • Updated tests.yml workflow to run build step before tests

    Noir cleanup

    Removed duplicate contracts that were consolidated in the base branch:

    • src/nr/initializerless/ (duplicate of src/nr/immutables/)
    • src/nr/schnorr_immutables_account_contract/ (duplicate of src/nr/schnorr_initializerless_account_contract/)

✨ PR Description

Purpose: Add comprehensive production infrastructure for initializerless immutables pattern with TypeScript SDK, benchmarks, and automated deployment workflows.

Main changes:

  • Implemented persistent CapsuleStore integration with store_immutables utility and artifact introspection via #[abi(immutables)] layout generation
  • Added complete TypeScript SDK with deployWithImmutables, serializeFromLayout, and account contract integration for SchnorrInitializerlessAccount
  • Configured CI/CD pipelines for PR benchmarks, pre-release publishing, and baseline tracking with aztec-benchmark integration

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Description using Guidelines Learn how

Base automatically changed from feat/nr-contracts to feat/constant-account February 11, 2026 14:32
@linear
Copy link
Copy Markdown

linear Bot commented Feb 11, 2026

AZT-707 JS Tests

# 🤖 Linear

Closes AZT-727

# Description

- Introduce persistent immutable storage via PXE CapsuleStore —
`store_immutables()` replaces per-transaction transient capsules with a
one-time `.simulate()` call after deployment
- Add `#[abi(immutables)]` layout generation to the `#[immutables]`
macro, enabling TypeScript artifact introspection
(`getImmutablesLayout`, `serializeFromLayout`)
- Add production-ready `deploySchnorrInitializerlessAccount()` to the
public API for npm consumers
- Rename publication options from
`skipClassPublication`/`skipInstancePublication` to opt-in
`publishClass`/`publishInstance` (default `false`)

  ## Changes

  ### Noir (`src/nr/`)
- **`#[immutables]` macro**: generates `Immutables::store(context,
capsule_data)` — validates `poseidon2_hash(capsule_data) ==
instance.salt` then persists to PXE CapsuleStore
- **`#[immutables]` macro**: generates `#[abi(immutables)]` layout
(field names, indices, serialized length) for TypeScript introspection —
mirrors `#[abi(storage)]` from aztec-nr
- **ImmutablesContract / SchnorrInitializerlessAccount**: add
`store_immutables` utility wrapper (manual, pending macro
auto-generation)

  ### TypeScript (`src/ts/`)
- **`immutables/utils.ts`**: add `getImmutablesLayout()`,
`serializeFromLayout()`, artifact layout validation in
`deployWithImmutables`, automatic `store_immutables().simulate()` call
during deployment, return
  `capsuleData: Fr[]` instead of `actualSalt: Fr`
- **`immutables/utils.ts`**: rename
`skipClassPublication`/`skipInstancePublication` →
`publishClass`/`publishInstance` (default `false`)
- **`schnorr-initializerless-account/index.ts`**: add
`deploySchnorrInitializerlessAccount()` (full lifecycle: key derivation,
deploy, Account creation), update `serializeSigningKey` to use
`serializeFromLayout`,
   return `capsuleData` from `computeSchnorrAccountAddress`
- **Delete `schnorr-initializerless-account/utils.ts`**: redundant with
`deploySchnorrInitializerlessAccount` in `index.ts`

  ### Tests
- All tests updated: `actualSalt` → `capsuleData`,
`registerInitializerlessAccount` →
`deploySchnorrInitializerlessAccount`, opt-in publication flags
- E2E tests use local `deployAndRegister` helper for TestWallet-specific
account registration

  ### Docs
- README rewritten: persistent store flow, `store_immutables` wrapper
docs, PXE recovery, npm usage examples, capsule data loss warning
Copy link
Copy Markdown

@linearb linearb Bot left a comment

Choose a reason for hiding this comment

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

✨ PR Review

LGTM

Generated by LinearB AI and added by gitStream.
AI-generated content may contain inaccuracies. Please verify before using.
💡 Tip: You can customize your AI Review using Guidelines Learn how

# 🤖 Linear

Closes AZT-708

# Description

  - Add account comparison benchmarks (immutables vs standard Schnorr)
- Set up npm package build (`yarn build`, subpath exports, `pre-release`
ready)
- Replace `build-aztec-standards` script with
`@defi-wonderland/aztec-standards` npm dependency
  - Remove counter contract and stale CI workflows
- Rename `SchnorrInitializerlessAccountContract` →
`SchnorrInitializerlessAccount` for the `AccountContract` impl
  - Update all import paths and README to use scoped package name

  ## Changes

  ### Benchmarks
- Add `benchmarks/account.benchmark.ts` — compares
`transfer_private_to_private` and `transfer_private_to_public` for both
account types
- Remove `benchmarks/counter.benchmark.ts` (measured the Dripper, not
the account)
- Add benchmark results section to README (+1,098 gates / +2.0%
entrypoint overhead)
- Use cleanup teardown pattern (replaces store.delete() +
process.exit(0))

  ### Build & Publishing
- Add `tsconfig.build.json`, `src/ts/index.ts` barrel, subpath exports
(`./immutables`, `./schnorr-initializerless-account`)
  - Scope package name to `@defi-wonderland/immutables-macro`
- Add `main`, `types`, `exports`, `files`, `publishConfig` to
`package.json`
  - Rename `src/ts/immutables/utils.ts` → `index.ts`

  ### Dependencies
- Add `@defi-wonderland/aztec-standards` (pre-release tarball) for
`TokenContract`
- Remove `scripts/build-aztec-standards.ts` and `build-aztec-standards`
script
  - Update Token imports in e2e tests and benchmarks

  ### Naming
- `SchnorrInitializerlessAccountContract` (class) →
`SchnorrInitializerlessAccount` — the codegen'd type keeps its natural
name
- `createSchnorrInitializerlessAccountContract()` →
`createSchnorrInitializerlessAccount()`
  - Remove `Handle` alias

  ### CI Workflows
- Replace inline `tests.yml` and `compare-benchmark.yml` with reusable
workflows (`main-tests.yml`, `pr-checks.yml`, `update-baseline.yml`)
  - Add `dist/` and `*.tsbuildinfo` to `.gitignore`
- Align all workflows with aztec-fee-payment/aztec-boilerplate (@v0
refs, separate benchmark job via aztec-benchmark)
  - Remove lint.yml (linting handled locally via husky/lint-staged)
  - Add pre-release.yml for npm pre-release workflow
 
  ### Cleanup
  - Remove `src/nr/counter_contract/` (Noir contract + tests)
  - Remove stale counter/Dripper references from `Nargo.toml`
  - Clean dead imports from `src/ts/utils.ts`
- Update Noir macro comments with version-tagged `aztec-packages`
permalink URLs
- Fix auth witness test: convert `action` to `FunctionCall` to avoid
`instanceof` mismatch across packages

<!--start_gitstream_placeholder-->
### ✨ PR Description
Purpose: Add production-ready benchmark infrastructure to measure and
compare gas costs and gate counts between Immutables Account and
Standard SchnorrAccount implementations.

Main changes:
- Implemented comprehensive account comparison benchmark measuring
transfer operations and initialization costs across account types
- Configured automated CI/CD workflows for PR benchmarking, baseline
updates, and pre-release publishing
- Refactored test utilities and package exports to support npm
publication with TypeScript definitions

_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->

---------

Co-authored-by: Weißer Hase <wei3erHase@protonmail.com>
@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 550,774 +Inf% 0 22,016 +Inf% 0 512 +Inf% N/A 7,226 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 588,359 +Inf% 0 12,800 +Inf% 0 149,749 +Inf% N/A 7,536 +Inf%
🆕 Standard Account: deploy + initialize 0 516,258 +Inf% 0 12,288 +Inf% 0 512 +Inf% N/A 7,066 +Inf%
🆕 Standard Account: transfer_private_to_private 0 549,676 +Inf% 0 22,016 +Inf% 0 512 +Inf% N/A 7,154 +Inf%
🆕 Standard Account: transfer_private_to_public 0 587,261 +Inf% 0 12,800 +Inf% 0 149,749 +Inf% N/A 7,574 +Inf%

## Description

Upgrades all Aztec dependencies from `4.0.0-devnet.1-patch.0` to
`4.0.0-devnet.2-patch.1`.

  ## Changes

  ### API migrations
  - `TestWallet` → `EmbeddedWallet` (new embedded wallet API)
- `SponsoredFeePaymentMethod` now required for on-chain contract class
publication (bytecode DA cost exceeds default fee juice balance)
- Publication payloads merged into a single transaction via
`mergeExecutionPayloads`, matching how `DeployMethod` bundles publish +
constructor in the SDK

  ### `CustomEmbeddedWallet`
- Replaced `registerCustomAccount` monkey-patch with a proper
`EmbeddedWallet` subclass
- Overrides `getAccountFromAddress` to support custom account types
(e.g. `SchnorrInitializerlessAccount`)
  - Shared across tests and benchmarks via `utils.ts`

  ### Fee sponsorship
- `setupTestSuite` now registers the canonical `SponsoredFPC` and
returns a `SponsoredFeePaymentMethod`
- `deployWithImmutables` accepts an optional `fee` for published
deployments
- `deploySchnorrAccount` accepts an optional `fee` forwarded to the
deploy method

  ### Housekeeping
- Deduplicated SponsoredFPC registration (was in e2e test, benchmark,
and utils separately)
- Moved `registerCustomAccount` from e2e test + benchmark into shared
`utils.ts`


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Upgrades to Aztec v4.0.0-devnet.2-patch.1, migrates to the new
EmbeddedWallet APIs, and renames the package to
@defi-wonderland/aztec-immutables-macro. Adds fee sponsorship support
and merges publication steps into a single transaction across utils,
tests, and benchmarks.

- **Migration**
- TestWallet → EmbeddedWallet; add CustomEmbeddedWallet with
registerCustomAccount for custom accounts.
- Setup registers SponsoredFPC and returns SponsoredFeePaymentMethod;
pass fee to deployWithImmutables, deployMixedUsageContract, and
deploySchnorrAccount.
- Publication now merges class + instance + init into one tx; fee
payload is prepended when provided.
- Replace wallet.createAccount(...) with
wallet.createSchnorrAccount(secret, salt).
  - Simulations query balances from the account’s own address as needed.
- Package renamed to @defi-wonderland/aztec-immutables-macro; README
import paths updated.
- Shared helpers consolidated in utils; duplicate SponsoredFPC
registration removed.

- **Dependencies**
- Bump all Aztec packages to 4.0.0-devnet.2-patch.1; add @aztec/wallets
and remove @aztec/test-wallet.
- Update Noir Nargo.toml aztec tags and aztec-benchmark GitHub workflow
refs to devnet.2-patch.1.
- Update aztec-standards prerelease tarball and package metadata
(name/version/repo).
  - Add wallet_data_* to .gitignore.

<sup>Written for commit 3c7ac35.
Summary will update on new commits.</sup>

<!-- End of auto-generated description by cubic. -->



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added support for sponsored fee payments in account deployments and
transactions.

* **Chores**
  * Package renamed to `@defi-wonderland/aztec-immutables-macro`.
  * Updated dependencies to Aztec 4.0.0-devnet.2-patch.1.
  * Enhanced wallet infrastructure for improved account management.

* **Documentation**
  * Updated README with new import paths for the renamed package.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • dev
  • main

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR restructures the aztec-immutables-macro repository from a boilerplate to a production-ready package. It removes legacy CI workflows (lint, tests, benchmark comparison) in favor of external reusable workflows from defi-wonderland repositories. The Noir macro implementation is rewritten to support immutables layout generation and persistence via a new store method. Legacy counter contract and immutables account variants are removed. Comprehensive TypeScript utilities for initializerless accounts, immutables deployment, and contract interaction are introduced. Package identity shifts to @defi-wonderland/aztec-immutables-macro with versioning aligned to 4.0.0-devnet.2-patch.1 and explicit ESM/TypeScript entry points.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'test: js' is vague and generic, providing minimal context about the substantial changes in this PR. Use a more descriptive title such as 'feat: add TypeScript SDK and E2E tests for immutables macro pattern' to clearly convey the main scope of this changeset.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and follows the template with a clear linked issue (AZT-707), detailed breakdown of changes, and organized sections covering utilities, integration, tests, and CI updates.
Linked Issues check ✅ Passed The PR successfully implements comprehensive TypeScript test suites, deployment utilities for the immutables macro, and account integration as required. All coding objectives for AZT-707 are met.
Out of Scope Changes check ✅ Passed The PR includes expected housekeeping changes (dependency updates, workflow refactoring, Nargo.toml updates) directly supporting the immutables feature delivery. Removed duplicate Noir contracts and workflow consolidations align with the PR's objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test/js

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,969 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,338 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,860 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,970 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,338 +Inf%

# 🤖 Linear

Closes AZT-XXX

<!--start_gitstream_placeholder-->
### ✨ PR Description
Purpose: Add production-ready TypeScript SDK and comprehensive
benchmarking infrastructure to enable initializerless account deployment
with persistent capsule storage for the Aztec immutables macro pattern.

Main changes:
- Implemented generic `deployWithImmutables` utility with automatic PXE
capsule persistence and artifact introspection via `#[abi(immutables)]`
layout
- Added account comparison benchmark measuring 516,258 gate
initialization cost savings versus 1,098 gate per-transaction overhead
- Created `Immutables::store()` method with salt validation to enable
PXE recovery after data loss

_Generated by LinearB AI and added by gitStream._
<sub>AI-generated content may contain inaccuracies. Please verify before
using.
💡 **Tip:** You can customize your AI Description using **Guidelines**
[Learn
how](https://docs.gitstream.cm/automation-actions/#describe-changes)</sub>
<!--end_gitstream_placeholder-->
@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,931 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,266 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,777 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,909 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,250 +Inf%

@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,018 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,313 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,857 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,981 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,284 +Inf%

@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,048 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,325 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,884 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,026 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,305 +Inf%

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/publish.yml">

<violation number="1" location=".github/workflows/publish.yml:43">
P0: **Security: Script injection via unsanitized `workflow_dispatch` input.**

`${{ github.event.inputs.version }}` is interpolated directly into the shell script, allowing command injection. Use an environment variable instead, which safely passes the value without shell interpretation.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/publish.yml Outdated
@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,990 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,323 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,894 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,003 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,355 +Inf%

@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,500 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,698 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 7,204 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,379 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,712 +Inf%

Copy link
Copy Markdown
Member

@wei3erHase wei3erHase left a comment

Choose a reason for hiding this comment

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

👍

@zkfrov zkfrov closed this Feb 27, 2026
@zkfrov zkfrov deleted the test/js branch February 27, 2026 20:03
@zkfrov zkfrov restored the test/js branch February 27, 2026 20:04
@zkfrov zkfrov changed the title test: js feat: #[immutables] macro, initializerless account, v4 upgrade with tests and benchmarks Feb 27, 2026
@zkfrov zkfrov reopened this Feb 27, 2026
@zkfrov zkfrov merged commit f4b2b7a into feat/constant-account Feb 27, 2026
9 checks passed
@zkfrov zkfrov deleted the test/js branch February 27, 2026 20:07
@github-actions
Copy link
Copy Markdown

Benchmark Comparison

CPU Cores RAM Arch
AMD EPYC 7763 64-Core Processor 16 63 GiB x64

Contract: account

Function Gates DA Gas L2 Gas Proving Time (ms)
Status Base PR Diff Base PR Diff Base PR Diff Base PR Diff
🆕 Immutables Account: transfer_private_to_private 0 537,939 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 7,147 +Inf%
🆕 Immutables Account: transfer_private_to_public 0 573,546 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,276 +Inf%
🆕 Standard Account: deploy + initialize 0 511,144 +Inf% 0 768 +Inf% 0 512 +Inf% N/A 6,783 +Inf%
🆕 Standard Account: transfer_private_to_private 0 536,841 +Inf% 0 1,312 +Inf% 0 512 +Inf% N/A 6,914 +Inf%
🆕 Standard Account: transfer_private_to_public 0 572,448 +Inf% 0 800 +Inf% 0 149,749 +Inf% N/A 7,247 +Inf%

@zkfrov zkfrov mentioned this pull request Mar 3, 2026
zkfrov added a commit that referenced this pull request Mar 6, 2026
# 🤖 Linear

Closes AZT-XXX

# Description

This branch introduces the **`#[immutables]` macro pattern** for Aztec
Noir contracts — a mechanism that allows contracts to store immutable
values committed via the contract's salt, eliminating the need for
an initializer transaction. It includes the Noir library, example
contracts, a full TypeScript SDK, tests, benchmarks, and CI
infrastructure.

   ## Noir Library & Contracts (PRs #8, #16, #19, #27)

- **`#[immutables]` comptime macro** (`src/nr/immutables/src/macro.nr`)
that generates:
     - `Serialize` / `Deserialize` implementations
- `Immutables::init(context)` — loads from capsule and verifies against
`instance.salt`
- `Immutables::init_unconstrained(context)` — unconstrained load without
verification
- Salt derivation: `salt = poseidon2_hash([actual_salt,
...serialized_immutables])`
- **`immutables_contract`** — Demo contract with both immutables and
mutable storage (mixed usage)
- **`schnorr_initializerless_account_contract`** — Account contract
using the initializerless pattern (signing key committed via salt, no
initializer needed)
- **`schnorr_account_contract`** — Standard Schnorr account with
initializer-based key storage (baseline for comparison)
- Noir TXE test scaffolding (most tests disabled pending
[aztec-packages#16656](AztecProtocol/aztec-packages#16656)
— TXE doesn't support custom salt)
   - Upgraded to Aztec `v4.0.0-devnet.1-patch.0`

   ## TypeScript SDK (PR #9)

- **`src/ts/immutables/`** — Generic utilities for deploying any
contract using `#[immutables]`:
     - `computeContractSalt(actualSalt, serializedImmutables)`
     - `createImmutablesCapsule(address, actualSalt, fields)`
     - `deployWithImmutables(wallet, artifact, fields, options?)`
- Supports both published (on-chain) and unpublished (PXE-only)
deployment
- **`src/ts/schnorr-initializerless-account/`** — Account contract
integration:
- `SchnorrInitializerlessAccountContract` (implements `AccountContract`
interface)
- `SchnorrInitializerlessAuthWitnessProvider` (Schnorr signature
creation)
- `registerInitializerlessAccount(wallet, options?)` — one-call
deployment + wallet registration
- `computeSchnorrAccountAddress(signingKey, options?)` — pre-compute
address before deployment

   ## Tests & Benchmarks (PR #9)

   | File | Description |
   |------|-------------|
| `schnorr-initializerless-account.test.ts` | 12 tests: deploy + read
key, different keys/salts → different addresses, wrong
capsule/actualSalt rejection, published + unpublished variants |
| `immutables-contract.test.ts` | Published/unpublished deploy, wrong
capsule rejection, mixed usage with initializer |
| `e2e.test.ts` | End-to-end with Dripper FPC: initializerless account
receives private tokens, transfers, balance checks vs standard
SchnorrAccount |
| `account.benchmark.ts` | Benchmark suite for account contract
operations |

   ## Documentation & CI (PRs #16, #19)

- Full README rewrite with usage guide, how-it-works explanation,
capsule documentation, and project structure
- CI workflows for PR checks, pre-release publishing, and baseline
tracking


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Immutables macro and initializerless immutables deployment workflow;
Schnorr account variants; TypeScript SDK for artifact introspection,
serialization, address precomputation, and deploy helpers; new account
benchmarks.

* **Documentation**
* README rewritten around immutables pattern, deployment/verification
guides and examples.

* **Tests**
* Comprehensive end-to-end test suites for immutables and Schnorr
account flows.

* **Chores**
* Removed legacy counter examples; CI/workflow reorganization; package
rebranding; updated pre-commit formatter and expanded .gitignore.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: frov <frov@wonderland.xyz>
Co-authored-by: Paperclip Minimizer <minim@wonderland.xyz>
Co-authored-by: Weißer Hase <84595958+wei3erHase@users.noreply.github.com>
Co-authored-by: Weißer Hase <wei3erHase@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants