TimandGitHub 495d3cc054 tests(mobile): e2e coverage for WalletConnectGate flows (#7760)
* tests(mobile): add e2e coverage for WalletConnectGate flows

Adds Maestro tests for the two non-signing gate states on the
review-and-execute screen:

- wc-gate-reconnect.yml: expired session renders "Reconnect wallet to
  continue"; tapping restores the session and reveals Execute transaction.
- wc-gate-switch-network.yml: wrong-network state renders "Switch network
  to continue"; tapping clears the flag and reveals Execute transaction.

Wires up the e2e control surface:

- WalletConnectContext.e2e.tsx: mock reconnect() and switchNetworkIfNeeded()
  now flip walletConnectE2eState so the gate transitions correctly.
- TestCtrls: e2eWcGateReconnect and e2eWcGateWrongNetwork buttons.
- connectSignerSetup: setupWcGateReconnect / setupWcGateWrongNetwork seed
  a pending-tx safe with a WC signer in the desired gate state.

Pin isows@1.0.7 in package.json resolutions.

Part of WA-1858.

* tests(mobile): extract shared review-and-execute nav for wc-gate tests

Both wc-gate YAML tests duplicated ~30 lines navigating from app start to
the Review-and-Execute screen of the first pending tx. Move that navigation
into apps/mobile/e2e/utils/setup/open-review-and-execute.yml, parameterised
by SETUP_BUTTON_ID, and have both gate tests `runFlow` it. The seeding
button id is now the only piece of per-test configuration.

* tests(mobile): assert wc-gate dismissal by id, not by neighbouring text

The gate-dismissed assertion used a regex matching either "Execute
transaction" or "Insufficient funds". Those are distinct semantic states
(funded vs unfunded signer); coupling them in one assertion lets a
funds-error regression silently pass the gate test.

Replace the text regex with `extendedWaitUntil: notVisible` on the gate
button id. That waits for re-render and asserts the gate is gone in one
step, decoupling the test from the underlying execute-button copy.

* tests(mobile): drop unread fields from WC e2e state overrides

WalletConnectGate and useWalletConnectStatus only read `address`,
`isWrongNetwork`, and `isWalletConnectSigner`. The setup helpers and the
`reconnect` mock were also setting `hasProvider` and `walletInfo` —
unobservable from any production code path, so they only added noise.

- setupWcGateReconnect: drop the override entirely; post-reset defaults
  already model an expired session.
- setupWcGateWrongNetwork: drop hasProvider and walletInfo.
- WalletConnectContext.e2e.tsx reconnect mock: drop hasProvider.

* tests(mobile): add `wc-gate` tag to connect-signer suite

The two child flows (wc-gate-reconnect.yml, wc-gate-switch-network.yml)
declare a `wc-gate` tag, but the parent __suite__.yml didn't surface it.
Tag-based runs (`maestro test --include-tags wc-gate`) now also pick up
the aggregated suite, matching repo convention.

* tests(mobile): annotate wcSigner literal with explicit Signer type

The literal relied on inference plus `as const` on `type`. With an explicit
Signer annotation, future widening or narrowing of the discriminated union
in signersSlice will surface here at compile time instead of failing
silently in the e2e flow. The `as const` workaround is no longer needed.

* tests(mobile): reuse setupPendingTxSafe from WC gate setup

setupWcGateBase duplicated the pending-tx safe scaffolding already in
setupHelpers.ts (base config, signer registration, active safe/signer).
The only delta was the signer's `type: 'walletconnect'` and the extra
setExecutionMethod dispatch.

Extend setupPendingTxSafe with an optional `options.signer` override.
Existing five private-key callers are unchanged. setupWcGateBase now
constructs the WC Signer literal and delegates everything else to the
shared helper.

* docs(mobile): document `e2e<PascalCase>` exception for TestCtrls triggers

The repo-wide testID convention is kebab-case, but every TestCtrls
scenario-trigger button uses `e2eConnectSignerOwner`-style camelCase.
That divergence was undocumented, so new contributors would either
churn the convention or get pushed to match it without context.

Codify the exception: product testIDs stay kebab-case; the hidden
e2e-build-only TestCtrls triggers use `e2e<PascalCase>`.

* docs: document `isows@1.0.7` resolution and add resolutions log

The root package.json `resolutions` block had 12 entries with zero
recorded rationale, so each new reviewer has to investigate why a pin
exists. Add `docs/resolutions.md` as the canonical home for that
rationale and seed it with the `isows@1.0.7` entry — a benign dedup
(no CVE) added to align the transitive version under viem.

Future contributors are asked to update the log alongside any new
resolutions entry.
2026-04-28 10:35:30 +02:00
2026-03-19 15:44:20 +01:00
2026-03-12 08:42:28 +01:00
2025-01-07 13:42:53 +01:00
2026-03-10 17:51:51 +01:00

Safe{Wallet}

Safe{Wallet} monorepo

🌐 Safe{Wallet} web app📱 Safe{Wallet} mobile app

Overview

Welcome to the Safe{Wallet} monorepo! Safe (formerly Gnosis Safe) is a multi-signature smart contract wallet for Ethereum and other EVM chains, requiring multiple signatures to execute transactions.

This repository houses both web and mobile applications along with shared packages, managed under a unified structure using Yarn Workspaces. The monorepo setup simplifies dependency management and ensures consistent development practices across projects.

Key components

  • apps/web - Next.js web application (detailed documentation)
  • apps/mobile - Expo/React Native mobile application (detailed documentation)
  • packages/store - Shared Redux store used by both platforms
  • packages/utils - Shared utilities and TypeScript types
  • config/ - Shared configuration files

Important

For detailed setup instructions and platform-specific development guides, please refer to the dedicated README files:

Getting started

To get started, ensure you have the required tools installed and follow these steps:

Prerequisites

  • Node.js: Install the latest stable version from Node.js.
  • Yarn: Use Yarn version 4.5.3 or later

to install it with the latest node version you can simply do

corepack enable

and then just run

yarn

This will install the required version of yarn and resolve all dependencies.

Note

Corepack is a tool to help with managing versions of your package managers. It exposes binary proxies for each supported package manager that, when called, will identify whatever package manager is configured for the current project, download it if needed, and finally run it.

Initial setup

  1. Clone the repository:
git clone <repo-url>
cd monorepo
  1. Install dependencies:
yarn install

Quick start commands

# Run web app in development mode
yarn workspace @safe-global/web dev

# Run mobile app in development mode
yarn workspace @safe-global/mobile start

# Run tests for web
yarn workspace @safe-global/web test

# Run Storybook for web
yarn workspace @safe-global/web storybook

Tip

For comprehensive setup instructions, environment variables, testing, and platform-specific workflows, see:

  • Web App README - Environment setup, Cypress E2E tests, Storybook, and more
  • Mobile App README - iOS/Android setup, Maestro E2E tests, Expo configuration, and more

Monorepo commands

Here are some essential commands to help you navigate the monorepo:

Workspace management

  • Run a script in a specific workspace:
yarn workspace <workspace-name> <script>

Example:

yarn workspace @safe-global/web dev
  • Add a dependency to a specific workspace:
yarn workspace <workspace-name> add <package-name>
  • Remove a dependency from a specific workspace:
yarn workspace <workspace-name> remove <package-name>

Note

Yarn treats commands that contain a colon as global commands. For example if you have a command in a workspace that has a colon and there isn't another workspace that has the same command, you can run the command without specifying the workspace name. For example:

yarn cypress:open

is equivalent to:

yarn workspace @safe-global/web cypress:open

Linting, formatting, and type-checking

  • Run ESLint across all workspaces:
yarn lint
  • Run Prettier to check formatting:
yarn prettier
  • Run type-check for a workspace:
yarn workspace @safe-global/web type-check
yarn workspace @safe-global/mobile type-check

Testing

  • Run unit tests across all workspaces:
yarn test
  • Run E2E tests (web only):
yarn workspace @safe-global/web cypress:open  # Interactive mode
yarn workspace @safe-global/web cypress:run   # Headless mode

Contributing

Adding a new workspace

  1. Create a new directory under apps/ or packages/.
  2. Add a package.json file with the appropriate configuration.
  3. Run:
yarn install

Best practices

  • Use Yarn Workspaces commands for managing dependencies.
  • Ensure type-check, lint, prettier, and tests pass before pushing changes.
  • Follow the semantic commit message guidelines.
  • For AI contributors, see AGENTS.md for detailed guidelines.

Tools & configurations

  • Husky: Pre-commit hooks for linting, formatting, and type-checking.
  • ESLint & Prettier: Enforce coding standards and formatting.
  • Jest: Unit testing framework.
  • Cypress: E2E testing for the web app.
  • Storybook: Component documentation and development for the web app.
  • Expo: Mobile app framework for the mobile workspace.
  • Next.js: React framework for the web workspace.
  • Tamagui: UI component library for the mobile app.

Release process

For information on releasing the web app, see the Automated Release Procedure.

Ode to the repo

In ages past when Gnosis laid the founding stone,
A vault was wrought that no single key could own.
Where signatures must gather ere the gate will yield,
M-of-N doth guard the treasure, sworn and sealed.

Now Yarn doth wind its threads through hall and bower,
Binding web and mobile in a single tower.
Redux keeps the ledger, RTK Query rides afar,
Returning with the fetched gold beneath the evening star.

Chain by chain the watchers set their vigil wide,
Across th' EVM kingdoms, ever at the Safe's own side.
Storybook doth chronicle each component's tale,
And Cypress walks the paths where lesser tests would fail.

No `any` types shall darken these well-guarded lands —
That ancient law doth hold by Prettier's own hands.
Feature flags like waypoints mark what lies ahead,
And lazy loads awaken only where the road doth tread.

Long the name hath wandered — Gnosis once, now Safe it stands,
Yet still the vow endureth, written into typed commands:
That what you hold stays guarded, deep beyond all theft or flame,
For this the codebase liveth — and security its name.

If you have any questions or run into issues, feel free to open a discussion or contact the maintainers. Happy coding! 🚀

S
Description
Safe{Wallet} fork with multi-brand (Safe / Lux / Hanzo) build targets — pnpm monorepo
Readme GPL-3.0
102 MiB
Languages
TypeScript 90.5%
JavaScript 7.5%
CSS 1.2%
Shell 0.4%
HTML 0.3%
Other 0.1%