Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jobs:
run: yarn noir:compile && yarn noir:codegen
- name: Compile Solidity contracts
run: yarn sol:compile
- name: Build TypeScript SDK
run: yarn ts:build
- name: Run hash compatibility check
run: bash e2e-tests/hash-compatibility.sh
- name: Run noir/aztec unit tests
Expand Down
73 changes: 73 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Publish SDK to npm

on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 0.2.0). Leave empty to use package.json version.'
required: false
type: string
dry_run:
description: 'Dry run (no actual publish)'
required: false
type: boolean
default: true

permissions:
contents: read

env:
NODE_VERSION: '24.12.0'
AZTEC_VERSION: 4.0.0-devnet.2-patch.0

jobs:
publish:
name: Build & Publish
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: publish-sdk-npm
cancel-in-progress: false
steps:
Comment thread
JanKuczma marked this conversation as resolved.
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'

- uses: ./.github/actions/setup-aztec
with:
version: ${{ env.AZTEC_VERSION }}

- name: Install dependencies
run: corepack enable && yarn install --frozen-lockfile

- name: Compile Noir contracts & generate bindings
run: yarn noir

- name: Build SDK
run: yarn ts:build

- name: Set version
if: inputs.version != ''
working-directory: ts/aztec-state-migration
env:
VERSION: ${{ inputs.version }}
run: |
[[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.]+)?$ ]] || { echo "Invalid semver: $VERSION"; exit 1; }
npm version "$VERSION" --no-git-tag-version

- name: Publish (dry run)
if: inputs.dry_run
working-directory: ts/aztec-state-migration
run: npm publish --access public --dry-run
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish
if: ${{ !inputs.dry_run }}
working-directory: ts/aztec-state-migration
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ dependencies
target
codegenCache.json
cache
ts/aztec-state-migration/noir-contracts
ts/aztec-state-migration/artifacts
e2e-tests/artifacts

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ yarn sol:deps
yarn noir:compile # Compile Noir contracts
yarn noir:codegen # Generate TypeScript bindings
yarn sol:compile # Compile Solidity contracts
yarn clean # Remove all compiled artifacts
yarn ts:build # Build typescript SDK
yarn clean # Remove all compiled and built artifacts
```

## Formatting
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/deploy-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
import type { AztecNode } from "@aztec/aztec.js/node";
import type { EmbeddedWallet } from "@aztec/wallets/embedded";
import type { AccountManager } from "@aztec/aztec.js/wallet";
import { MigrationEmbeddedWallet } from "../ts/aztec-state-migration/wallet/migration-embedded-wallet.js";
import { MigrationEmbeddedWallet } from "aztec-state-migration/wallet/base";

export interface DeploymentResult {
[rollupVersion: number]: {
Expand Down
19 changes: 1 addition & 18 deletions e2e-tests/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { fileURLToPath } from "url";
import { getPXEConfig } from "@aztec/pxe/server";
import { getInitialTestAccountsData } from "@aztec/accounts/testing";
import type { DeploymentResult } from "./deploy-types.js";
import { NodeMigrationEmbeddedWallet } from "../ts/aztec-state-migration/wallet/index.js";
import { NodeMigrationEmbeddedWallet } from "aztec-state-migration/wallet";

const __dirname = dirname(fileURLToPath(import.meta.url));

Expand All @@ -32,23 +32,6 @@ const ETHEREUM_RPC_URL =
const ANVIL_PRIVATE_KEY =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";

// ============================================================
// L1 ABIs (exported for event parsing in tests)
// ============================================================
export const L1MigratorAbi = parseAbi([
"constructor(address _registry, address _poseidon2)",
"function migrateArchiveRoot(uint256 oldVersion, (bytes32 actor, uint256 version) l2Migrator) external returns (bytes32 leaf, uint256 leafIndex)",
"function getArchiveInfo(uint256 version) external view returns (bytes32 archiveRoot, uint256 provenBlockNumber)",
"function REGISTRY() external view returns (address)",
"function POSEIDON2() external view returns (address)",
"function SECRET_HASH_FOR_ZERO() external view returns (bytes32)",
"event ArchiveRootMigrated(uint256 indexed oldVersion, uint256 indexed newVersion, bytes32 indexed l2Migrator, bytes32 archiveRoot, uint256 provenBlockNumber, bytes32 messageLeaf, uint256 messageLeafIndex)",
]);

export const InboxAbi = parseAbi([
"event MessageSent(uint256 indexed checkpointNumber, uint256 index, bytes32 indexed hash, bytes16 rollingHash)",
]);

// ============================================================
// Bytecode loaders
// ============================================================
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/migration-key-registry.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EmbeddedWallet } from "@aztec/wallets/embedded";
import { createAztecNodeClient } from "@aztec/aztec.js/node";
import { MigrationKeyRegistryContract } from "../ts/aztec-state-migration/noir-contracts/MigrationKeyRegistry.js";
import { MigrationKeyRegistryContract } from "aztec-state-migration/noir-contracts";
import { Fq, Fr } from "@aztec/foundation/curves/bn254";
import { getInitialTestAccountsData } from "@aztec/accounts/testing";
import { generatePublicKey } from "@aztec/aztec.js/keys";
Expand Down
26 changes: 12 additions & 14 deletions e2e-tests/migration-mode-a.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ExampleMigrationAppV1Contract } from "./artifacts/ExampleMigrationAppV1.js";
import { ExampleMigrationAppV2Contract } from "./artifacts/ExampleMigrationAppV2.js";
import { Fr } from "@aztec/foundation/curves/bn254";
import { signMigrationModeA } from "../ts/aztec-state-migration/index.js";
import { signMigrationModeA } from "aztec-state-migration/mode-a";
import { deploy } from "./deploy.js";
import {
deployAppPair,
Expand Down Expand Up @@ -106,12 +106,11 @@ async function main() {
// Step 5: Bridge archive root
// ============================================================
console.log("Step 5. Bridging archive root...");
const { l1Result, provenBlockNumber, blockHeader } = await bridgeBlock(
const { provenBlockNumber, blockHeader } = await bridgeBlock(
env,
newArchiveRegistry,
);
console.log(` Proven block: ${l1Result.provenBlockNumber}`);
console.log(` Archive root: ${l1Result.provenArchiveRoot}\n`);
console.log(` Proven block: ${provenBlockNumber}`);

// ============================================================
// Steps 6-7: Prepare migration args and call migrate on NEW rollup
Expand All @@ -129,11 +128,12 @@ async function main() {
`Expected exactly 1 migration note, but found ${lockNotesAndData.length}`,
);
}
const lockNoteAndData = lockNotesAndData[0];

// Build proofs via wallet, combining note proofs with event data
const [migrationNoteProof] = await oldUserWallet.buildMigrationNoteProofs(
const migrationNoteProof = await oldUserWallet.buildMigrationNoteProof(
provenBlockNumber,
lockNotesAndData,
lockNoteAndData,
);

// Sign via standalone function
Expand Down Expand Up @@ -248,12 +248,10 @@ async function main() {
console.log("Step 10. Bridging archive root for public lock note...");

const {
l1Result: l1ResultPublic,
provenBlockNumber: publicProvenBlockNumber,
blockHeader: publicBlockHeader,
} = await bridgeBlock(env, newArchiveRegistry);
console.log(` Proven block: ${l1ResultPublic.provenBlockNumber}`);
console.log(` Archive root: ${l1ResultPublic.provenArchiveRoot}\n`);
console.log(` Proven block: ${publicProvenBlockNumber}`);

// ============================================================
// Step 11: Get public lock note and merkle proofs
Expand Down Expand Up @@ -287,12 +285,12 @@ async function main() {
`Expected exactly 1 migration note for the public lock, but found ${filteredNotes.length}`,
);
}
const migrationNote = filteredNotes[0];

const [publicMigrationNoteProof] =
await oldUserWallet.buildMigrationNoteProofs(
publicProvenBlockNumber,
filteredNotes,
);
const publicMigrationNoteProof = await oldUserWallet.buildMigrationNoteProof(
publicProvenBlockNumber,
migrationNote,
);

// Sign via standalone function
const publicSignature = await signMigrationModeA(
Expand Down
23 changes: 11 additions & 12 deletions e2e-tests/migration-mode-b.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Fr } from "@aztec/foundation/curves/bn254";
import { signMigrationModeB } from "../ts/aztec-state-migration/index.js";
import { signMigrationModeB } from "aztec-state-migration/mode-b";
import { deploy } from "./deploy.js";
import {
deployAppPair,
Expand All @@ -12,8 +12,8 @@ import {
} from "./test-utils.js";
import { ExampleMigrationAppV1Contract } from "./artifacts/ExampleMigrationAppV1.js";
import { ExampleMigrationAppV2Contract } from "./artifacts/ExampleMigrationAppV2.js";
import { MigrationKeyRegistryContract } from "../ts/aztec-state-migration/noir-contracts/MigrationKeyRegistry.js";
import { UintNote } from "../ts/aztec-state-migration/common-notes.js";
import { MigrationKeyRegistryContract } from "aztec-state-migration/noir-contracts";
import { UintNote } from "aztec-state-migration/common-notes";
import { NoteStatus } from "@aztec/stdlib/note";

async function main() {
Expand Down Expand Up @@ -204,12 +204,12 @@ async function main() {
}

// The ExampleMigrationApp currently only creates one note per call.
const balanceNotes = balanceNotesActive.slice(0, 1);
const balanceNote = balanceNotesActive[0];

// Build proofs via wallet
const fullProofs = await oldUserWallet.buildFullNoteProofs(
const fullProof = await oldUserWallet.buildFullNoteProof(
provenBlockNumber,
balanceNotes,
balanceNote,
(note) => UintNote.fromNote(note),
);

Expand All @@ -227,7 +227,7 @@ async function main() {
oldMigrationSigner,
blockHeader.global_variables.version,
new Fr(env.newRollupVersion),
balanceNotes,
[balanceNote],
newUserManager.address,
newApp.address,
);
Expand All @@ -240,8 +240,7 @@ async function main() {
console.log("Step 10. Calling migrate_mode_b on NEW rollup...");

// The ExampleMigrationApp currently only supports migrating one note at a time.
const noteProof = fullProofs[0];
const migrateAmount = noteProof.note_proof_data.data.value;
const migrateAmount = fullProof.note_proof_data.data.value;
console.log(` Migrating amount: ${migrateAmount}`);

const newBalanceBefore = await newAppUser.methods
Expand All @@ -252,7 +251,7 @@ async function main() {
await newAppUser.methods
.migrate_mode_b(
signature,
noteProof,
fullProof,
blockHeader,
oldUserManager.address,
publicKeys,
Expand Down Expand Up @@ -290,9 +289,9 @@ async function main() {
// Take one nullified note
const nullifiedNote = balanceNotesNullified[0];

const [nullifiedNoteProof] = await oldUserWallet.buildFullNoteProofs(
const nullifiedNoteProof = await oldUserWallet.buildFullNoteProof(
provenBlockNumber,
[nullifiedNote],
nullifiedNote,
(note) => UintNote.fromNote(note),
);

Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/migration-public-mode-b.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import {
ExampleMigrationAppV2Contract,
ExampleMigrationAppV2ContractArtifact,
} from "./artifacts/ExampleMigrationAppV2.js";
import { MigrationKeyRegistryContract } from "../ts/aztec-state-migration/noir-contracts/MigrationKeyRegistry.js";
import { MigrationKeyRegistryContract } from "aztec-state-migration/noir-contracts";
import { AztecAddress } from "@aztec/stdlib/aztec-address";
import {
buildPublicDataProof,
buildPublicMapDataProof,
} from "../ts/aztec-state-migration/mode-b/proofs.js";
} from "aztec-state-migration/mode-b";
import { randomBigInt } from "@aztec/foundation/crypto/random";

// Define a struct that matches the one used in the example app contract,
Expand Down
24 changes: 12 additions & 12 deletions e2e-tests/nft-migration-mode-a.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NftMigrationAppV1Contract } from "./artifacts/NftMigrationAppV1.js";
import { NftMigrationAppV2Contract } from "./artifacts/NftMigrationAppV2.js";
import { Fr } from "@aztec/foundation/curves/bn254";
import { signMigrationModeA } from "../ts/aztec-state-migration/index.js";
import { signMigrationModeA } from "aztec-state-migration/mode-a";
import { deploy } from "./deploy.js";
import {
deployNftAppPair,
Expand Down Expand Up @@ -115,11 +115,11 @@ async function main() {
// ============================================================
console.log("Step 5. Bridging archive root...");

const { l1Result, provenBlockNumber, blockHeader } = await bridgeBlock(
const { provenBlockNumber, blockHeader } = await bridgeBlock(
env,
newArchiveRegistry,
);
console.log(` Proven block: ${l1Result.provenBlockNumber}\n`);
console.log(` Proven block: ${provenBlockNumber}\n`);

// ============================================================
// Step 6: Get migration notes and build proofs
Expand All @@ -136,10 +136,11 @@ async function main() {
`Expected exactly 1 migration note, but found ${lockNotesAndData.length}`,
);
}
const lockNoteAndData = lockNotesAndData[0];

const [migrationNoteProof] = await oldUserWallet.buildMigrationNoteProofs(
const migrationNoteProof = await oldUserWallet.buildMigrationNoteProof(
provenBlockNumber,
lockNotesAndData,
lockNoteAndData,
);

const oldMigrationSigner = await oldUserWallet.getMigrationSignerFromAddress(
Expand Down Expand Up @@ -259,11 +260,10 @@ async function main() {
console.log("Step 11. Bridging archive root for public lock...");

const {
l1Result: l1ResultPublic,
provenBlockNumber: publicProvenBlockNumber,
blockHeader: publicBlockHeader,
} = await bridgeBlock(env, newArchiveRegistry);
console.log(` Proven block: ${l1ResultPublic.provenBlockNumber}\n`);
console.log(` Proven block: ${publicProvenBlockNumber}\n`);

// ============================================================
// Step 12: Get notes, filter, build proof
Expand Down Expand Up @@ -293,12 +293,12 @@ async function main() {
`Expected exactly 1 remaining note, but found ${filteredNotes.length}`,
);
}
const filteredNote = filteredNotes[0];

const [publicMigrationNoteProof] =
await oldUserWallet.buildMigrationNoteProofs(
publicProvenBlockNumber,
filteredNotes,
);
const publicMigrationNoteProof = await oldUserWallet.buildMigrationNoteProof(
publicProvenBlockNumber,
filteredNote,
);

const publicSignature = await signMigrationModeA(
oldMigrationSigner,
Expand Down
Loading