Skip to content
This repository was archived by the owner on Jul 10, 2026. It is now read-only.

feat: add js tests - #361

Merged
0xLeopoldo merged 1 commit into
feat/1155from
feat/1155-js-tests
Jul 7, 2026
Merged

feat: add js tests#361
0xLeopoldo merged 1 commit into
feat/1155from
feat/1155-js-tests

Conversation

@0xLeopoldo

Copy link
Copy Markdown
Contributor

🤖 Linear

Closes AZT-XXX

Description

add js tests

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add MultiToken end-to-end Vitest coverage

🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Add Vitest E2E happy-path coverage for MultiToken state-mutating methods.
• Introduce MultiToken-specific deploy, commitment, and TransferSingle event helpers.
• Validate public/private balances, privacy expectations, and authwit flows via real SDK stack.
Diagram

graph TD
  A["Vitest: multitoken.test.ts"] --> B["Test helpers: utils.ts"] --> C["Aztec SDK Wallet"] --> D["PXE/Node"] --> E["MultiToken contract"] --> F["Public logs"]
  A -->|"assert balances"| E
  B -->|"decode TransferSingle"| F

  subgraph Legend
    direction LR
    _test["Test"] ~~~ _mod["Helper module"] ~~~ _svc["Service"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Filter logs by event selector (or ABI metadata) instead of field-count
  • ➕ More robust if other events with 4 fields are added later
  • ➕ Reduces risk of false positives when decoding logs
  • ➖ May require extra SDK plumbing if selector/tag access isn’t straightforward
  • ➖ Slightly more code than the current “4 fields” heuristic
2. Avoid wallet internals for commitments by using public SDK return-value plumbing
  • ➕ Less brittle than reaching into privateExecutionResult
  • ➕ Aligns with supported API surface and reduces maintenance cost
  • ➖ May not be currently possible without upstream SDK changes
  • ➖ Could block tests until the SDK supports private return values cleanly

Recommendation: Current approach is reasonable for adding pragmatic E2E coverage now (and it already flags the wallet-internals escape hatch with a TODO). Consider tightening event filtering to use an event selector/tag once available to prevent future ambiguity as the contract emits more events.

Files changed (2) +550 / -0

Tests (2) +550 / -0
multitoken.test.tsAdd MultiToken end-to-end happy-path Vitest suite +369/-0

Add MultiToken end-to-end happy-path Vitest suite

• Introduces E2E tests covering deploy/view reads, mint variants (public/private/commitment), transfer variants across public/private/commitment, and burn flows. Validates privacy expectations (no public events in private-only flows), correct balance updates, and TransferSingle event decoding. Demonstrates public and private authwit flows, including additionalScopes for third-party submission.

src/ts/test/multitoken.test.ts

utils.tsAdd MultiToken deploy/commitment helpers and TransferSingle log assertions +181/-0

Add MultiToken deploy/commitment helpers and TransferSingle log assertions

• Adds constants and utilities for MultiToken name/symbol encoding round-trip, contract deployment with a configurable minter/auth hook, and commitment initialization via wallet internals. Introduces MultiToken-specific public log querying and decoding for the 4-field TransferSingle event, plus an assertion helper for event sequences.

src/ts/test/utils.ts

@qodo-code-review

qodo-code-review Bot commented Jul 7, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Ambiguous log decoding 🐞 Bug ☼ Reliability
Description
getMultiTokenTransferEvents decodes every public log with 4 emitted fields as TransferSingle, so any
other 4-field log from the same contract/tx will be mis-decoded and can make tests flaky or assert
the wrong events. The code even documents the TransferSingle selector but does not use it to
disambiguate logs before decoding.
Code

src/ts/test/utils.ts[R911-919]

+  return response.logs
+    .filter((extLog) => {
+      const eventFields = extLog.log.getEmittedFieldsWithoutTag();
+      return eventFields.length === expectedFieldCount;
+    })
+    .map((extLog) => {
+      const eventFields = extLog.log.getEmittedFieldsWithoutTag();
+      return decodeFromAbi([eventMetadata.abiType], eventFields) as MultiTokenTransferEvent;
+    });
Evidence
The helper selects logs solely by emitted field count and decodes them as TransferSingle; a nearby
comment states an explicit selector but no selector-based filtering is implemented.

src/ts/test/utils.ts[911-919]
src/ts/test/utils.ts[771-776]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`getMultiTokenTransferEvents` currently filters public logs by `eventFields.length === 4` and decodes all matches as `TransferSingle`. This is not a unique discriminator: if `MultiToken` ever emits another 4-field event/log (or internal/public logs change shape), the helper will decode the wrong event type, breaking ordering/count assertions or producing false positives.

## Issue Context
There is already a comment documenting the expected selector (`0x2429b477`), but the implementation doesn’t use the selector/tag to filter.

## Fix Focus Areas
- src/ts/test/utils.ts[899-920]
- src/ts/test/utils.ts[771-777]

## Suggested fix
- Filter logs using a unique event discriminator (preferably the log tag / event selector associated with `MultiTokenContract.events.TransferSingle`) before decoding.
- Keep the field-count check as a secondary guard, not the primary selector.
- If the SDK exposes an event selector/tag on `eventMetadata`, compare it against the log’s tag; otherwise, consider catching decode failures and discarding non-matching logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unchecked commitment indexing 🐞 Bug ☼ Reliability
Description
initializeMultiTokenTransferCommitment assumes nestedExecutionResults[0].returnValues[0] exists
and will throw a TypeError if the nested execution layout differs or the call fails in an unexpected
way, obscuring the real failure cause. This makes debugging commitment-related test failures
significantly harder.
Code

src/ts/test/utils.ts[R867-870]

+  const entrypoint = provenTx.privateExecutionResult.entrypoint;
+  const nestedResults = entrypoint.nestedExecutionResults;
+  const returnValues = nestedResults[0].returnValues;
+  const commitment = returnValues[0].toBigInt();
Evidence
The new helper indexes into nested results and return values without any guards, so it will throw a
runtime error if those arrays are empty/undefined.

src/ts/test/utils.ts[854-875]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`initializeMultiTokenTransferCommitment` directly indexes `nestedExecutionResults[0]` and `returnValues[0]` without validating array lengths or presence. If proving changes its nesting structure (or the call fails and returns no values), the helper will crash with a generic `Cannot read properties of undefined` instead of a clear error.

## Issue Context
This helper is used as a prerequisite for commitment-completion flows (mint/transfer to commitment). When it fails, the downstream tests will fail in confusing ways.

## Fix Focus Areas
- src/ts/test/utils.ts[854-877]

## Suggested fix
- Add explicit checks:
 - `nestedExecutionResults?.length > 0`
 - `nestedExecutionResults[0]?.returnValues?.length > 0`
- If missing, throw an Error that includes:
 - function name (`initialize_transfer_commitment`)
 - tx hash (if available)
 - a short summary of the observed execution structure.
- Optionally assert the extracted commitment is non-zero before returning.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

  • Author self-review: I have reviewed the code review findings, and addressed the relevant ones.

Qodo Logo

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Benchmark Comparison

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

Contract: escrow

🚦 Function Gates DA Gas L2 Gas Proving Time (ms)
Base PR Diff Base PR Diff Base PR Diff Base PR Diff
(partial) withdraw 536,844 536,844 1,312 1,312 495,400 495,400 6,989 7,098 +109 (+1.6%)
withdraw 536,844 536,844 736 736 483,700 483,700 6,997 7,043 +46 (+0.7%)
withdraw_nft 503,323 503,323 736 736 483,700 483,700 6,817 6,922 +105 (+1.5%)

Contract: logic

🚦 Function Gates DA Gas L2 Gas Proving Time (ms)
Base PR Diff Base PR Diff Base PR Diff Base PR Diff
get_escrow 488,339 488,339 128 128 456,000 456,000 6,688 6,817 +129 (+1.9%)
secret_key_to_public_keys 483,417 483,417 128 128 456,000 456,000 6,643 6,735 +92 (+1.4%)
share_escrow 387,745 387,745 704 704 474,500 474,500 5,883 5,955 +72 (+1.2%)

Contract: nft

🚦 Function Gates DA Gas L2 Gas Proving Time (ms)
Base PR Diff Base PR Diff Base PR Diff Base PR Diff
burn_private 422,217 422,217 416 416 661,169 661,169 6,180 6,267 +87 (+1.4%)
burn_public 308,698 308,698 448 448 670,145 670,145 5,242 5,332 +90 (+1.7%)
mint_to_private 439,895 439,895 960 960 652,042 652,042 6,259 6,375 +116 (+1.9%)
mint_to_public 308,698 308,698 448 448 670,790 670,790 5,212 5,262 +50 (+1.0%)
transfer_private_to_private 394,899 394,899 736 736 483,700 483,700 5,896 6,060 +164 (+2.8%)
transfer_private_to_public 422,293 422,293 416 416 659,249 659,249 6,127 6,228 +101 (+1.6%)
transfer_public_to_private 436,536 436,536 960 960 652,459 652,459 6,302 6,352 +50 (+0.8%)
transfer_public_to_public 308,698 308,698 384 384 633,270 633,270 5,196 5,296 +100 (+1.9%)

Contract: token

🚦 Function Gates DA Gas L2 Gas Proving Time (ms)
Base PR Diff Base PR Diff Base PR Diff Base PR Diff
burn_private 451,655 451,655 992 992 683,010 683,010 6,431 6,474 +43 (+0.7%)
burn_public 308,698 308,698 448 448 672,479 672,479 5,287 5,320 +33 (+0.6%)
initialize_transfer_commitment 371,233 371,233 704 704 474,500 474,500 5,779 5,859 +80 (+1.4%)
mint_to_private 440,787 440,787 960 960 652,048 652,048 6,361 6,391 +30 (+0.5%)
mint_to_public 308,698 308,698 448 448 672,077 672,077 5,206 5,379 +173 (+3.3%)
transfer_private_to_commitment 408,890 408,890 896 896 495,400 495,400 5,997 6,122 +125 (+2.1%)
transfer_private_to_private 428,414 428,414 1,312 1,312 495,400 495,400 6,181 6,271 +90 (+1.5%)
transfer_private_to_public 451,804 451,804 992 992 683,154 683,154 6,359 6,458 +99 (+1.6%)
transfer_private_to_public_with_commitment 455,247 455,247 1,568 1,568 716,454 716,454 6,377 6,500 +123 (+1.9%)
transfer_public_to_commitment 308,698 308,698 576 576 662,454 662,454 5,212 5,325 +113 (+2.2%)
transfer_public_to_private 442,082 442,082 960 960 652,435 652,435 6,297 6,335 +38 (+0.6%)
transfer_public_to_public 308,698 308,698 448 448 672,473 672,473 5,270 5,321 +51 (+1.0%)

Contract: vault

🚦 Function Gates DA Gas L2 Gas Proving Time (ms)
Base PR Diff Base PR Diff Base PR Diff Base PR Diff
deposit_private_to_private 861,408 861,408 1,280 1,280 846,950 846,950 9,767 9,896 +129 (+1.3%)
deposit_private_to_private_exact 970,252 970,252 1,856 1,856 883,784 883,784 10,651 10,802 +151 (+1.4%)
deposit_private_to_public 679,000 679,000 768 768 861,772 861,772 8,264 8,399 +135 (+1.6%)
deposit_public_to_private 554,293 554,293 1,344 1,344 889,542 889,542 7,221 7,274 +53 (+0.7%)
deposit_public_to_private_exact 709,509 709,509 1,920 1,920 926,538 926,538 8,473 8,697 +224 (+2.6%)
deposit_public_to_public 308,698 308,698 832 832 905,432 905,432 5,207 5,343 +136 (+2.6%)
issue_private_to_private_exact 970,252 970,252 1,856 1,856 884,441 884,441 10,608 10,787 +179 (+1.7%)
issue_private_to_public_exact 834,152 834,152 1,344 1,344 899,488 899,488 9,521 9,768 +247 (+2.6%)
issue_public_to_private 604,635 604,635 1,344 1,344 898,736 898,736 7,616 7,729 +113 (+1.5%)
issue_public_to_public 308,698 308,698 832 832 906,119 906,119 5,217 5,299 +82 (+1.6%)
redeem_private_to_private_exact 971,471 971,471 1,856 1,856 884,288 884,288 10,721 10,826 +105 (+1.0%)
redeem_private_to_public 678,850 678,850 768 768 862,210 862,210 8,201 8,330 +129 (+1.6%)
redeem_public_to_private_exact 710,879 710,879 1,920 1,920 926,862 926,862 8,516 8,584 +68 (+0.8%)
redeem_public_to_public 308,698 308,698 832 832 905,954 905,954 5,226 5,297 +71 (+1.4%)
withdraw_private_to_private 862,627 862,627 1,280 1,280 847,160 847,160 9,777 9,941 +164 (+1.7%)
withdraw_private_to_private_exact 971,471 971,471 1,856 1,856 884,237 884,237 10,661 10,737 +76 (+0.7%)
withdraw_private_to_public_exact 834,001 834,001 1,344 1,344 899,719 899,719 9,516 9,669 +153 (+1.6%)
withdraw_public_to_private 555,653 555,653 1,344 1,344 889,362 889,362 7,194 7,294 +100 (+1.4%)
withdraw_public_to_public 308,698 308,698 832 832 906,257 906,257 5,225 5,331 +106 (+2.0%)

@zkfrov zkfrov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@0xLeopoldo
0xLeopoldo merged commit 0ab4a8c into feat/1155 Jul 7, 2026
6 checks passed
@0xLeopoldo
0xLeopoldo deleted the feat/1155-js-tests branch July 7, 2026 12:49
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants