Skip to content

✅ e2e: add borrow asset flow#710

Merged
cruzdanilo merged 8 commits intomainfrom
e2e
Feb 2, 2026
Merged

✅ e2e: add borrow asset flow#710
cruzdanilo merged 8 commits intomainfrom
e2e

Conversation

@cruzdanilo
Copy link
Member

@cruzdanilo cruzdanilo commented Feb 2, 2026


Open with Devin

Summary by CodeRabbit

  • Accessibility

    • Added an aria-label to the loan amount selector for improved screen reader support.
  • New Features

    • Provider/wallet: submit grouped calls and query per-call status/receipts.
    • UI automation: new borrow-asset flow for end-to-end borrowing scenarios.
  • Chores / Tests

    • Expanded e2e testing and mocks, local verification services via Docker, tests now run in watch mode, and test orchestration/teardown streamlined.

@changeset-bot
Copy link

changeset-bot bot commented Feb 2, 2026

🦋 Changeset detected

Latest commit: 09ea4d9

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

Walkthrough

Adds an i18n aria-label to the loan amount input; introduces a Maestro borrowAsset subflow and updates local flow; extends Anvil typings and on-chain log processing; implements e2e multi-tx send/status handling; expands e2e/docker test infra and persona mocks; and updates test scripts/package.json.

Changes

Cohort / File(s) Summary
Accessibility & release note
src/components/loans/AmountSelector.tsx, .changeset/tender-sloths-judge.md
Adds i18n-based aria-label to the loan amount input and a changeset declaring a patch release for the accessibility change.
Maestro flows & subflow
.maestro/flows/local.yaml, .maestro/subflows/borrowAsset.yaml
Adds borrowAsset subflow and updates local flow to capture portfolioBefore, run borrowAsset (amount=10, installments=4), include platform-specific UI repeats, re-read portfolio, and assert a +10 net change.
Anvil RPC typings
.maestro/src/anvil.ts
Adds overloads for anvil RPC: eth_blockNumber and typed eth_getLogs returning RpcLog[]; imports RpcLog.
Proposal hook & log processing
.maestro/src/script/hookProposals.ts
After mining, captures eth_blockNumber, computes block range, fetches ERC20 Transfer logs via eth_getLogs, reads token decimals, normalizes values and emits activity per transfer.
E2E wallet call tracking
src/utils/e2e.ts
wallet_sendCalls now sends calls, returns a composite id of tx hashes; adds wallet_getCallsStatus to parse the id, fetch receipts via publicClient.getTransactionReceipt, and return status/receipts.
Test harness & anvil orchestration
server/test/anvil.ts, server/script/e2e.ts, server/package.json
Unconditional Anvil startup and Forge script execution, docker-aware orchestration/teardown and verification, Vitest switched to watch mode, and generate:broadcasts sets NODE_ENV=development.
Docker Compose for e2e services
server/test/docker-compose.yaml
Adds docker-compose stack (otterscan, sourcify, postgres, migrations, schema-fix) with init/migration and service orchestration for local verification and contract verification steps.
Persona & e2e mocks
server/test/e2e.ts
Replaces minimal persona mock with a richer stateful mock exposing inquiry/document/account helpers (getPendingInquiryTemplate, getInquiry, createInquiry, resumeInquiry, getDocument, addDocument, getAccounts, getAccount).
Spellcheck config
cspell.json
Adds erigon, ipfs, otterscan, and sourcify to the spellcheck ignore word list.

Sequence Diagram(s)

sequenceDiagram
  participant TestRunner as TestRunner
  participant Maestro as Maestro
  participant UI as UI
  participant Server as Server
  participant Anvil as Anvil

  TestRunner->>Maestro: start local flow
  Maestro->>Maestro: evalScript -> capture portfolioBefore
  Maestro->>UI: run subflow borrowAsset (taps/inputs/submit)
  UI->>Anvil: submit transaction(s)
  Anvil-->>UI: tx hashes / mined block
  Maestro->>Anvil: eth_blockNumber / eth_getLogs (from..to)
  Anvil-->>Maestro: Transfer logs (RpcLog[])
  Maestro->>Server: activity(logs) / sync nonces
  Maestro->>Maestro: read portfolioAfter
  Maestro->>TestRunner: assert portfolioAfter - portfolioBefore == 10
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • nfmelendez
  • dieguezguille
  • franm91
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main objective: adding an end-to-end borrow asset flow, which is reflected across multiple file changes including the new borrowAsset.yaml flow, updated test infrastructure, and related e2e testing enhancements.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch e2e

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link

Summary of Changes

Hello @cruzdanilo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a comprehensive end-to-end test for the asset borrowing functionality, ensuring its stability and correctness. It significantly upgrades the local testing infrastructure by incorporating Docker Compose for essential blockchain development tools like Otterscan and Sourcify, streamlining contract verification and debugging. Additionally, it includes an important accessibility improvement for the loan amount selector and refines the e2e wallet interaction handling.

Highlights

  • New E2E Borrow Asset Flow: Implemented a comprehensive end-to-end test flow for borrowing assets using Maestro, ensuring the stability and correctness of this critical functionality.
  • Enhanced Local Testing Infrastructure: Upgraded the local development environment with Docker Compose to integrate essential blockchain development tools like Otterscan (block explorer) and Sourcify (contract verification), streamlining debugging and contract validation.
  • Accessibility Improvement: Improved user experience for assistive technologies by adding an 'aria-label' to the loan amount input field in the UI.
  • Advanced E2E Wallet Interaction Handling: Updated e2e testing utilities to support batching multiple transactions via 'wallet_sendCalls' and retrieving their collective status with 'wallet_getCallsStatus', enabling more complex and realistic test scenarios.
  • On-chain Activity Tracking for Proposals: Integrated new logic into Maestro scripts to track on-chain transfer activities related to proposals using 'eth_getLogs', enhancing visibility into test execution.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional flags.

Open in Devin Review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds an end-to-end test for the 'borrow asset' flow. The changes include new Maestro test flows, scripts to interact with the blockchain during tests, and significant improvements to the local e2e testing environment, such as integrating a local block explorer and contract verifier using Docker. Mocks for services like Persona have also been enhanced to support more complex test scenarios. Overall, this is a great step towards improving test coverage and developer experience. I've found one bug in the test utility for contract verification and suggested a fix.

@sentry
Copy link

sentry bot commented Feb 2, 2026

Codecov Report

❌ Patch coverage is 41.66667% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.86%. Comparing base (2a3f748) to head (09ea4d9).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
src/utils/e2e.ts 36.36% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #710      +/-   ##
==========================================
+ Coverage   64.59%   65.86%   +1.26%     
==========================================
  Files         173      190      +17     
  Lines        5387     5996     +609     
  Branches     1505     1734     +229     
==========================================
+ Hits         3480     3949     +469     
- Misses       1727     1867     +140     
  Partials      180      180              
Flag Coverage Δ
e2e 47.42% <41.66%> (+4.29%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cruzdanilo cruzdanilo force-pushed the e2e branch 2 times, most recently from 56b09aa to 81a43a1 Compare February 2, 2026 01:23
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 9 additional flags in Devin Review.

Open in Devin Review

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/test/anvil.ts (2)

225-307: ⚠️ Potential issue | 🟡 Minor

Add retry/readiness checks around Sourcify verification to prevent startup races.

Sourcify service lacks a healthcheck in docker-compose.yaml, so docker compose up -d --wait returns before it's ready to handle verification requests. Add retry logic to the verify calls (lines 237–269) to handle temporary unavailability during startup.


1-24: ⚠️ Potential issue | 🟡 Minor

Guard on docker compose availability, not just daemon status and add missing reason to eslint annotation.

docker info can succeed even when the compose plugin is missing, so the subsequent compose calls may fail. Additionally, the eslint-disable-line directive at line 202 is missing the required reason explanation per the coding guidelines.

Suggested fixes

Line 21:

-  const docker = env.NODE_ENV === "e2e" && !env.CI && (await $`docker info`.then(() => true).catch(() => false));
+  const docker = env.NODE_ENV === "e2e" && !env.CI && (await $`docker compose version`.then(() => true).catch(() => false));

Line 202:

-  const files = await readdir(__dirname, { recursive: true }); // eslint-disable-line unicorn/prefer-module
+  const files = await readdir(__dirname, { recursive: true }); // eslint-disable-line unicorn/prefer-module -- controlled access to test directory
🤖 Fix all issues with AI agents
In @.maestro/flows/local.yaml:
- Around line 50-66: The YAML linter errors are caused by inconsistent spacing
around inline flow mappings and inline comments in the borrow flow block; update
the inline mappings used by evalScript, runFlow (env), runFlow (when), and the
repeat while visible mappings so there is exactly one space after '{' and one
before '}' (e.g., env: { amount: "10", installments: "4" } -> ensure spaces
inside the braces) and ensure inline comments have a single space before the '#'
(e.g., change "- runFlow:# HACK" style to "- runFlow: # HACK"); apply this
spacing consistently for the symbols evalScript, runFlow, env, when, repeat,
while, and visible to satisfy YAMLlint.

In @.maestro/src/script/hookProposals.ts:
- Around line 42-49: The loop currently converts large ERC-20 amounts to Number
which loses precision; change the activity() signature to accept value: bigint |
string and update its implementation and all callers accordingly, then in
.maestro/src/script/hookProposals.ts pass the raw BigInt(log.data) (i.e.,
BigInt(log.data)) from the logs loop instead of Number(BigInt(log.data)); ensure
any downstream code that consumes activity(account, value) handles bigint or
string (e.g., serialization to string for logging/storage) to avoid runtime/type
errors.
- Around line 37-40: Replace the indefinite busy-wait while loop that calls
readContract({ address: proposalManagerAddress, functionName: "nonces", args:
[account], abi: proposalManagerAbi }) < nextNonce with a bounded polling loop:
add a maxRetries counter and iterate up to that limit, calling readContract each
iteration and breaking when the nonce >= nextNonce; if maxRetries is exceeded,
throw or return an error so the caller/orchestration layer can handle retry (or
delegate to runFlow's extendedWaitUntil). Wrap the polling in try/catch around
readContract to surface RPC errors, and reference the symbols readContract,
proposalManagerAddress, proposalManagerAbi, account, and nextNonce when
implementing the change.

In @.maestro/subflows/borrowAsset.yaml:
- Around line 7-32: YAML linter errors are caused by extra spaces inside
inline-mapping braces; tighten spacing for all inline mappings (e.g., change "{
visible: Explore decentralized services }" to "{visible: Explore decentralized
services}", "{ tapOn: Connect wallet to Exactly Protocol }" to "{tapOn: Connect
wallet to Exactly Protocol}", "{ id: Amount }" to "{id: Amount}", and "{
account: "${output.account}" }" to "{account: "${output.account}"}") across the
keys shown (when, commands, tapOn, runFlow, runScript env, etc.); update every
occurrence of inline braces in this subflow so there are no spaces immediately
after "{" or before "}" to satisfy YAMLlint.

In `@server/script/e2e.ts`:
- Line 14: The current spawn call starts Vitest in persistent watch mode (const
v = spawn(...)), which is inappropriate for CI; modify the spawn invocation that
creates v to choose args based on process.env.CI so CI runs a single pass.
Specifically, replace the hardcoded ["--watch"] with a conditional like: const
args = process.env.CI ? ["run"] : ["--watch"]; then call spawn("vitest", args, {
stdio: ["ignore","pipe","pipe"], env: { ...process.env, FORCE_COLOR: "1" } });
keep the variable name v and existing stdio/env options unchanged.

In `@server/test/anvil.ts`:
- Around line 202-222: Replace the inline disable comment after the readdir call
with a preceding eslint-disable-next-line that includes a reason; specifically,
remove the trailing "// eslint-disable-line unicorn/prefer-module" after the
invocation of readdir(...) and add a line above it: "// eslint-disable-next-line
unicorn/prefer-module -- <reason>" (keeping the call to readdir(__dirname, {
recursive: true }) as-is) so the rule is disabled with the required annotation
format.

In `@server/test/docker-compose.yaml`:
- Around line 4-23: Replace the two "latest" images with pinned tags or digests
to ensure reproducible e2e runs: change "image: otterscan/otterscan:latest" and
"image: ghcr.io/ethereum/sourcify/server:latest" to explicit version tags or
immutable digests (e.g., otterscan/otterscan:<version> and
ghcr.io/ethereum/sourcify/server@sha256:<digest>), update any CI/test configs
that assume "latest", and document the chosen tags so tests can be reproduced;
verify by running the e2e suite to confirm no behavior change.
- Around line 41-90: The docker-compose YAML uses compact brace-style mappings
and hardcoded secrets; change all inline brace mappings in services (e.g.,
depends_on entries for postgres, migrations, schema-fix) to explicit block-style
mappings with proper spacing and ensure comments have a preceding space, and
replace hardcoded credentials (POSTGRES_PASSWORD, PGPASSWORD and any
SESSION_SECRET usage) with environment variable references (e.g., use
${POSTGRES_PASSWORD} and ${PGPASSWORD} or ${SESSION_SECRET} with sensible
defaults only for local dev) so secrets are injected from the environment or a
.env file; update the postgres, schema-fix and migrations service environment
fields to reference these variables and ensure healthcheck/depends_on condition
keys remain valid after rebasing to block style.
- Around line 3-20: The otterscan service's OTTERSCAN_CONFIG uses "erigonURL":
"http://localhost:8545" which is unreachable from inside the container; update
the OTTERSCAN_CONFIG in the otterscan service to point erigonURL to
"http://host.docker.internal:8545" (same pattern as the Sourcify service) so the
container can reach the host's Anvil instance.

process.stderr.on("error", () => null);
const v = spawn("vitest", ["run"], { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, FORCE_COLOR: "1" } });
const v = spawn("vitest", ["--watch"], { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, FORCE_COLOR: "1" } });
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n server/script/e2e.ts

Repository: exactly/exa

Length of output: 1676


🏁 Script executed:

# Check if there are other scripts using similar patterns for CI detection
rg "process\.env\.CI|CI.*spawn|vitest" --type ts --type js -B2 -A2

Repository: exactly/exa

Length of output: 12848


🏁 Script executed:

# Check how the e2e script is typically invoked
find . -type f -name "package.json" -o -name "*.yml" -o -name "*.yaml" | head -20

Repository: exactly/exa

Length of output: 730


🏁 Script executed:

# Check package.json scripts
rg "e2e" package.json -A2 -B2

Repository: exactly/exa

Length of output: 2598


🏁 Script executed:

# Check workflow files for e2e.ts invocation
rg "e2e" .github/workflows/test.yaml -A3 -B3

Repository: exactly/exa

Length of output: 1475


🏁 Script executed:

# Search for how vitest watch mode is typically handled
rg "spawn.*vitest|--watch" --type ts --type js

Repository: exactly/exa

Length of output: 197


Gate watch mode to interactive environments; use run mode in CI.

Vitest's --watch mode continuously monitors files and never exits on its own. While the current HTTP shutdown mechanism works, this approach is semantically incorrect—watch mode should only be used for local development. CI environments should use vitest run for single execution. Use process.env.CI (automatically set by GitHub Actions and standard CI systems) to conditionally select the appropriate mode:

Suggested fix
-const v = spawn("vitest", ["--watch"], { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, FORCE_COLOR: "1" } });
+const v = spawn("vitest", [process.env.CI ? "run" : "--watch"], { stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, FORCE_COLOR: "1" } });
🤖 Prompt for AI Agents
In `@server/script/e2e.ts` at line 14, The current spawn call starts Vitest in
persistent watch mode (const v = spawn(...)), which is inappropriate for CI;
modify the spawn invocation that creates v to choose args based on
process.env.CI so CI runs a single pass. Specifically, replace the hardcoded
["--watch"] with a conditional like: const args = process.env.CI ? ["run"] :
["--watch"]; then call spawn("vitest", args, { stdio: ["ignore","pipe","pipe"],
env: { ...process.env, FORCE_COLOR: "1" } }); keep the variable name v and
existing stdio/env options unchanged.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In @.maestro/flows/local.yaml:
- Around line 50-66: Yamllint is flagging brace and inline-comment spacing in
the borrow block (look for the evalScript line and the three runFlow blocks,
plus the env and when mappings and the repeat/visible entries); fix by adding a
space after every opening brace and before every closing brace in inline
mappings (e.g., "{ amount: \"10\", installments: \"4\" }", "{ true:
\"${maestro.platform != 'web'}\" }", "{ platform: web }", and "{ visible: { id:
Pending proposals } }") and ensure inline comments use a single space before the
"#" and are separated from the preceding value (e.g., "runFlow:  # HACK ...");
apply the same spacing rules to the repeat/visible/commands lines so yamllint no
longer reports brace/comment spacing errors.
- Around line 67-68: Add a retry/read loop that invokes the existing
readPortfolio subflow repeatedly before performing the assertTrue check so the
asynchronous portfolio update is observed reliably; specifically, replace the
single runFlow: ../subflows/readPortfolio.yaml followed immediately by
assertTrue with a retry pattern (same as used earlier after minting) that calls
runFlow: ../subflows/readPortfolio.yaml up to N times with a short delay/backoff
and breaks once output.portfolio - output.portfolioBefore === 10 is true, then
perform the assertTrue on output.portfolio to fail only after exhausting
retries.

In @.maestro/src/script/hookProposals.ts:
- Around line 37-40: The spin loop that calls readContract({ address:
proposalManagerAddress, functionName: "nonces", args: [account], abi:
proposalManagerAbi }) < nextNonce in hookProposals.ts will busy-wait and spike
CPU; modify the loop to await a short sleep between iterations (e.g., await new
Promise(r => setTimeout(r, 100))) or use any provided Maestro sleep utility,
ensure the enclosing function is async, and keep the same condition using the
nonces read so you still break once nonces >= nextNonce.
- Line 49: The loop calling activity(log.address, account,
Number(BigInt(log.data))) can lose precision for values >
Number.MAX_SAFE_INTEGER; change to preserve full integer precision by passing
BigInt or a string instead of converting to Number: update the call site in the
logs loop and adjust the activity(...) signature/consumers (and any downstream
types) to accept a BigInt or string representation (e.g., BigInt(log.data) or
log.data.toString()) so large token amounts are handled without precision loss.

In @.maestro/subflows/borrowAsset.yaml:
- Around line 3-4: The existing assertion checks for amount and installments
only verify presence and numeric-ness but allow negatives and fractions; update
the assertTrue conditions that reference amount and installments so amount is a
positive integer (Number(amount) > 0 and Number.isInteger(Number(amount))) and
installments is a positive integer (Number(installments) > 0 and
Number.isInteger(Number(installments))); locate and replace the two assertTrue
expressions that use ${amount ...} and ${installments ...} to enforce these
positive-integer constraints so UI labels like "X installments of" always
receive valid whole, positive counts and amounts.

In `@server/test/docker-compose.yaml`:
- Line 4: The docker-compose uses floating :latest tags for otterscan/otterscan
and ghcr.io/ethereum/sourcify/server which harms reproducibility; update the
image entries for those services (otterscan/otterscan and
ghcr.io/ethereum/sourcify/server) to a fixed tag or immutable digest (e.g.,
specific version tag or sha256 digest) instead of :latest, ensuring both
occurrences are changed and commit the updated compose file so the test
environment uses pinned images.

In `@server/test/e2e.ts`:
- Line 94: Remove the extraneous blank line separating the two test calls so
resumeInquiry and getDocument are adjacent; open server/test/e2e.ts, locate the
sequence where resumeInquiry(...) is followed by an empty line and then
getDocument(...), and delete that blank line so the calls sit on consecutive
lines in accordance with the compact style guideline.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/components/loans/AmountSelector.tsx`:
- Line 94: Change the aria-label on the AmountSelector component to use a
full-sentence i18n string instead of the terse "Amount": update the aria-label
prop (in src/components/loans/AmountSelector.tsx where aria-label={t("Amount")}
is used) to call t with a full-sentence key/value (e.g., t("Select the loan
amount in dollars")) or the repository's agreed i18n key that maps to a full
sentence so screen readers get contextual information; ensure the exact key
matches existing i18n files or add the new sentence to the translations.

In `@src/utils/e2e.ts`:
- Around line 62-77: The wallet_getCallsStatus RPC handler throws a vague
Error("bad"); change it to use the consistent error wording used elsewhere
(e.g., throw new Error("bad params")) so callers get uniform messages; update
the error thrown in the case "wallet_getCallsStatus" (where params, isHex and id
are validated) to the same phrasing used by other handlers like "bad params".

@cruzdanilo cruzdanilo force-pushed the e2e branch 2 times, most recently from dce1252 to b1b5b78 Compare February 2, 2026 03:19
@cursor
Copy link

cursor bot commented Feb 2, 2026

PR Summary

Medium Risk
Moderate risk because it changes e2e wallet/provider behavior and expands Anvil test setup (including optional Docker services and contract verification), which could affect test reliability and developer workflows.

Overview
Adds a new end-to-end borrowAsset Maestro subflow and extends the main local Maestro flow to borrow USDC via installments, then verifies the portfolio delta after proposals settle.

Enhances Maestro blockchain scripting by adding eth_blockNumber/eth_getLogs support and updating hookProposals to wait for proposal execution and emit ERC-20 Transfer activity events based on on-chain logs.

Improves local/e2e infrastructure: the mobile e2e window.ethereum shim now supports wallet_sendCalls with deterministic IDs and wallet_getCallsStatus receipt aggregation; server e2e runs Vitest in watch mode; Anvil test setup always initializes fixtures and can spin up Otterscan/Sourcify via Docker to verify deployed contracts; and the loan amount input gains an i18n-backed aria-label (with a changeset + cspell dictionary updates).

Written by Cursor Bugbot for commit 09ea4d9. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@cruzdanilo cruzdanilo merged commit 09ea4d9 into main Feb 2, 2026
15 of 16 checks passed
@cruzdanilo cruzdanilo deleted the e2e branch February 2, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant