22 Commits
Author SHA1 Message Date
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
86500d78bd chore(mobile): upgrade Tamagui from v1 to v2 (#7497)
* chore(mobile): upgrade Tamagui from v1 to v2

Upgrade all @tamagui/* packages from v1 (^1.126.3) to v2 (2.0.0-rc.26).
Replace deprecated @tamagui/animations-moti with animations-reanimated.
Rewrite SafeButton to use v2 compound component pattern (Button.Text)
with correct font weight, disabled state, and icon coloring.
Patch @tamagui/image for style override bug (upstream fix merged but
not yet on npm: https://github.com/tamagui/tamagui/pull/3966).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): resolve Tamagui tokens in Loader before passing to SVG

The Loader component passes color directly to react-native-progress
(CircleSnail), which uses react-native-svg internally. SVG doesn't
understand Tamagui theme tokens like "$color", causing repeated
"not a valid color or brush" console warnings.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): center nav bar title in scrollable headers

Remove flex: 1 from headerTitle Animated.View so the native stack
header centers the title element itself. Add headerTitleAlign: 'center'
and match right spacer width (40px) to the back button circle.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): fix Tamagui v2 component API breakages

- SafeButton: rewrite with Button.Text compound pattern, add textColor
  prop for forced light-mode overrides, restore fontWeight 700 default
- SafeInput: replace removed `editable` prop with `readOnly`, use
  GetProps<StyledInput> to fix type conflicts, cast theme tokens
- SafeCard: use `src` instead of `source`, `objectFit` instead of
  `resizeMode` for Tamagui v2 Image
- ParametersButton: migrate from raw Button to SafeButton
- Badge: fix dark mode background token (backgroundMain → borderLight)
- Raw Buttons: move fontWeight to Button.Text in ImportSigner/Ledger
- Onboarding: migrate color prop to textColor for dark mode fix
- Assets errors: use secondary variant + textColor instead of inline bg

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): preserve element children and text-button accent color in SafeButton

- Only wrap string/number children in Button.Text; render element
  children (ActivityIndicator, Loader) directly to avoid invalid
  text-child nesting on native.
- Use theme.primary for the text variant so text-style buttons
  retain their accent color instead of blending with body text.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): replace raw Tamagui Button with SafeButton in ImportSuccess

The Copy button on the signer import success screen was broken after the
Tamagui v2 upgrade because it used a raw Tamagui Button. Replace it with
SafeButton (secondary, $sm) for consistent styling and v2 compatibility.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): fix Jest transform config for Tamagui v2 and update snapshots

Add tamagui and @tamagui/* to transformIgnorePatterns so Jest can parse
the ESM exports in Tamagui v2. Update 22 snapshots reflecting the new
style output and remove stale fontFamily assertion in DataRow test.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

---------

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-03-20 16:39:59 +01:00
c166a5a44e fix(mobile): upgrade react-native-quick-crypto for Android 16KB page size (#7480)
* fix(mobile): upgrade react-native-quick-crypto for Android 16KB page size support

Upgrade react-native-quick-crypto from 0.7.x to 1.0.17 to support
Android 16KB page size requirement. Add react-native-nitro-modules and
react-native-quick-base64 as new peer dependencies. Update
react-native-device-crypto patch to remove deprecated jcenter()
repository references for Gradle 9.0 compatibility.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* chore(mobile): remove unused config/ethers.ts

Dead code — crypto-shims.ts in platform/ is the active version
imported by the root layout.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): deduplicate react-native-quick-base64 via resolution

Add root resolution to force a single copy of react-native-quick-base64
(2.2.2), avoiding version skew between the direct dependency and the
transitive one from @craftzdog/react-native-buffer.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): upgrade react-native-mmkv to v4 and pin MMKV pod

- Upgrade react-native-mmkv from 3.x to 4.2.0 (Nitro-based rewrite)
- Migrate API: new MMKV() -> createMMKV(), .delete() -> .remove()
- Pin MMKV pod to ~> 2.3.0 in notification extension plugin instead
  of master branch, fixing sharedApplication build error in App
  Extensions
- Update expo plugin config.ts (source of truth for Podfile template)

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* docs: add solution doc for Expo native file editing workflow

Document that generated native files (ios/Podfile etc.) must be
modified through Expo config plugins, not directly. Also unignore
docs/solutions/ from .gitignore.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(mobile): add jest mocks for react-native-nitro-modules and mmkv v4

MMKV v4 uses NitroModules under the hood, which requires mocking in
the test environment. Add mocks for both react-native-nitro-modules
and the new react-native-mmkv createMMKV API.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>

---------

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-03-19 13:28:26 +01:00
4329678a09 refactor(web): migrate Swap to new feature architecture (#7084)
* refactor(swap): migrate to v3 feature architecture

- Create contract.ts defining public API surface with typed exports
- Create feature.ts with flat structure for lazy-loaded components
- Create index.ts with feature handle and direct hook exports
- Move SwapWidget from index.tsx to components/SwapWidget/
- Extract getSwapTitle to helpers/utils.ts
- Add FallbackSwapWidget to contract and feature

Update all consumers (~20 files) to use the v3 pattern:
- Components accessed via useLoadFeature(SwapFeature)
- Hooks imported directly from @/features/swap
- Utilities/constants imported directly from @/features/swap

All consumers now use proper public API imports instead of
internal paths like @/features/swap/components/* or
@/features/swap/hooks/*


Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* fix(swap): convert internal imports to relative paths

Convert absolute @/features/swap/* imports to relative paths within
the swap feature to satisfy ESLint import restrictions.

Internal components and hooks now use relative imports:
- components/SwapOrder/index.tsx: ../OrderId, ../StatusLabel, etc.
- components/SwapOrderConfirmationView/*: ../OrderId, ../SwapTokens, etc.
- hooks/__tests__/*: ../useIsExpiredSwap, ../useIsTWAPFallbackHandler

Also fix external consumers:
- SignMessage: import selectSwapParams from @/features/swap
- store/slices.ts: import from @/features/swap barrel


Co-authored-by: Hanzo Dev <dev@hanzo.ai>

* docs(web): eslint gotcha on feature refactoriing

* refactor(web): move swapTx to transactions

* fix(web): don’t directly import feature files

* refactor(web): use swap title directly

* fix(web): import swap

* refactor(web): remove unused hook

* fix(web): export store from store folder

* fix(web): duplicate import

* fix: import swap errors

* fix(web): add pr feedback

---------

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-03-05 16:12:39 +01:00
daniel-safe 1ad4f06758 docs(mobile): move docs to correct locations
The mobile docs were in the wrong directory (caused by the monorepo move)
2025-02-12 11:11:47 +00:00
a5f73da4c0 Feat(Mobile): private key and safe account management
* Update docs (#53)

* docs: move contributing to code-style

The contributing doc is actually a code-style doc. Once we move
everything to monorepo we will adopt the safe-wallet-web
CONTRIBUTING.md file.

* docs: add release procedure docs

(cherry picked from commit 01345f008492e9a5d33fc5e198966e6be4d5452c)

* Feat: Add create/get private key hook (#59)

* feat: add necessary libraries

* feat: create useSign hook

* feat: cover sign hook with unit tests

* Update apps/mobile/src/hooks/useSign/useSign.ts

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>

* fix: adjust type

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>

* feat: add react-native-quick-crypto back

* fix: lint uintGenericArray problem

* fix: adjust export style

* fix: remove duplicated lines from gitignore

* chore: add reference link

* fix: typo on useSign unit tests

* chore: store iv in the keychain

* Update apps/mobile/src/hooks/useSign/useSign.ts

Co-authored-by: Usame Algan <5880855+usame-algan@users.noreply.github.com>

* fix: typo in unit tests

---------

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>
Co-authored-by: Usame Algan <5880855+usame-algan@users.noreply.github.com>
(cherry picked from commit 45e82f7ee28fd349669e70e5a3e259e88675743f)

* feat: create account management functionality (#60)

* feat: create useSign hook

* feat: add react-native-quick-crypto back

* feat: create chainsDisplay component to show the grouped chains images

* chore: move redux provider to the top of the react three to make the bottomSheet provider able to read values from redux selectors

* feat: create badge variant for using the badge component in the chainsDisplay component according to figma

* feat: add testIDs in the chainsDisplay component

* feat: allow user to provider a footer to the dropdown component

* chore: make the logo size dynamically

* feat: create AccountCard component

* feat: create AccountItem component to handle the dropdown events and specific layout

* feat: replace the image component by the chainsDisplay component in the Balances component

* feat: change the color of the active chain in the chain selection dropdown

* feat: create a footer for MyAccounts dropdown

* feat: remove unnecessary tests

* feat: add accounts management feature inside the navbar dropdown

* feat: create useInfiniteScroll hook to handle infinite scroll functionality

* feat: use activeChain information into the tokens container

* feat: make the Identicon component to be more extensible

* feat: add mocked constants inside the store folder

* feat: create safes slice to store all safes added into the app

* feat: add possibility to get all supported chains ids and get them also by id

* chore: auto generated types

* chore: remove unused types

* feat: create MyAccounts container

* feat: use isFetching instead isLoading to avoid cached result while query is being revalidated

* chore: memoize the chains manipulation in the chainsDisplay component

* chore: create an useMyAccountsService hook to handle pos-fetch logic outside the container

(cherry picked from commit be1a137b30984b8fcc866fd6767824f5f67ec659)

* chore: update yarn.lock

* chore: link code style file with CONTRIBUTING.md

---------

Co-authored-by: Daniel Dimitrov <daniel@compojoom.com>
2024-12-27 09:35:25 +03:00
Daniel Dimitrov 2b09baf72c refactor: move nextjs files to apps/web 2024-12-19 20:26:14 +01:00
katspaughandGitHub 1702bd6390 Chore: extract terms version into a separate file for a smaller build (#4584) 2024-12-02 09:43:39 +01:00
James MealyandGitHub 6210e5f232 Docs: update release docs with missing step (#4489) 2024-11-06 14:27:40 +01:00
3174658e0a docs: how to update terms.md (#4220)
* docs: how to update terms.md

* Update docs/update-terms.md

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>

* Update docs/update-terms.md

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>

* Update docs/update-terms.md

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>

---------

Co-authored-by: katspaugh <381895+katspaugh@users.noreply.github.com>
2024-09-20 15:59:10 +02:00
katspaughandGitHub 35e319263d Chore: update the PR review domain (#3620)
* Chore: update the PR review domain

* Update docs
2024-04-29 11:41:51 +02:00
katspaughandGitHub 81c720b640 Docs: Update release-procedure.md 2024-02-08 10:58:52 +01:00
Daniel DimitrovandGitHub 6104b8f70d docs: improve the “preparing a release” steps (#3170) 2024-01-30 10:08:10 +01:00
katspaughandGitHub fcd4b6720f Docs: update environments.md 2023-11-23 11:38:43 +01:00
815093f614 Docs: update release-procedure.md (#2447)
* Docs: update release-procedure.md

* Update docs/release-procedure.md

Co-authored-by: Aaron Cook <aaron@safe.global>

---------

Co-authored-by: Aaron Cook <aaron@safe.global>
2023-08-28 10:31:24 +02:00
katspaughandGitHub 2df64e4c62 Chore: rename PR deployment folder (#1944) 2023-05-04 15:39:27 +02:00
Aaron CookandGitHub ea063cd756 chore: remove EIP-1271 docs (#1761) 2023-03-13 11:07:47 +01:00
7c084988e5 [Epic] EIP-1271 support (#1162)
* feat: add "Messages" to transactions (#1161)

* feat: add "Messages" to transactions

* fix: spelling mistake + remove unnecessary prop

* feat: EIP-1271 accordion w/ summary (#1163)

* feat: basic message accordion w/ summary

* fix: single message view

* fix: tooltip text

* fix: remove single view

* fix: revert button text

* fix: review adjustments + add test

* fix: test description

* feat: EIP-1271 accordion details (#1201)

* feat: basic message accordion w/ summary

* fix: single message view

* fix: tooltip text

* fix: remove single view

* feat: EIP-1271 accordion details

* fix: prettify typed data

* fix: default expansion of confirmation

* fix: add copy buttons to hash/signature

* feat: message signer stepper (#1211)

* feat: basic message accordion w/ summary

* fix: single message view

* fix: tooltip text

* fix: remove single view

* feat: EIP-1271 accordion details

* fix: prettify typed data

* fix: default expansion of confirmation

* fix: add copy buttons to hash/signature

* feat: message signer stepper

* fix: separator lengths

* fix: tweak separator

* fix: adjust logic, icons + spacing

* feat: EIP-1271 event bus, notifications + statuses (#1216)

* feat: EIP-1271 event bus, notifications + statuses

* fix: adjust events, status hook + extend tests

* fix: test

* feat: `msgsSlice` store slice (#1217)

* feat: EIP-1271 event bus, notifications + statuses

* feat: `msgsSlice` store slice

* fix: load messages

* feat: basic message signing modal (#1224)

* feat: EIP-1271 event bus, notifications + statuses

* feat: `msgsSlice` store slice

* fix: load messages

* feat: basic message signing modal

* fix: test

* fix: add missing argument

* fix: add test template

* feat: basic signing modal

* fix: image

* fix: rename slice

* fix: rename `messages` to `signedMessages`

* fix: rename to Safe messages

* fix: use `SafeAppIcon`

* feat: connect list, propose and confirm endpoints (#1243)

* feat: connect list, propose and confirm endpoints

* fix: add missing `await`

* fix: polling + adjust comments

* fix: poll `messagesTag` on tag change (#1273)

* fix: poll on tag change

* fix: regenerate lock file + rename hook

* [EIP-1271] `communicator` integration (#1270)

* feat: communicator integration

* fix: multiple fixes around message signing

- pending state of msgs
- registers middleware
- confirm message onSign if already proposed
- RPC calls from safe apps

Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com>

* feat: notification for messages w/o confirmation

* fix: decode message before hashing

* fix: handle encoded messages in MsgModal

* add: error handling in MsgModal

Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com>

* fix: merge issues

* test: adjust deployment workflow

* test: revert deploy workflow

* test: skip integrity check

* test: modify checksum

* test: update checksums

* fix: remove log

* fix: check if signature exists if tag changes

* fix: adjust naming + dependencies

* fix: add test for awaiting messages

* fix: use store, return empty string + add tests

* fix: return `settings`

* fix: add test coverage to `MsgModal`

* fix: workflows, file names, tests + version check

* fix: check EIP-1271 support

Co-authored-by: schmanu <manu@safe.global>
Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com>

* fix: rename label

* fix: show message hash

* [EIP-1271] fix: remove explorer link from prepare signature (#1396)

* fix: remove explorer link from prepare signature

* fix: mocks

* fix: rename label

* fix: modal header text + smaller message font (#1399)

* fix: EIP-712 message display in transaction list

* fix: poll for messages (#1402)

* fix: check for compatibility handler (#1417)

* fix: make message expandable (#1461)

* fix: git workflow

* fix: rename tooltip and label for SignTxButton (#1466)

* [EIP-1271] support Safe's < 1.3.0 (#1465)

Does not use the chainId in the domainSeparator for <1.3.0 Safes

* fix: add what are signed messages link to page (#1459)

* fix: add what are signed messages link to page

* show link only if there are messages

* extract SignedMessagesHelpLink to a different file

* suppressIcon -> noIcon

* fix: move message below link (#1486)

* docs: eip-1271 developer docs

* docs: change url to tx service in examples

* docs: reformulate some sections of eip-1271 docs

* [Eip-1271] normalize EIP-712 messages (#1518)

* fix: message positioning (#1538)

* fix: message positioning

* fix: labels

* feat: use EIP1271 feature toggle per chain (#1555)

* fix: adjust message display style (#1557)

* [EIP-1271] Decode eip712 messages (#1580)

* fix: decode nested object arrays correctly

* chore: update packages

* fix: add analytics event

* chore: remove unecessary action

* fix: track via message bus

* fix: memoisations, split tracking hooks

* fix: add `ErrorBoundary`

* fix: update docs

* fix: add help centre link

---------

Co-authored-by: schmanu <manu@safe.global>
Co-authored-by: Aaron Cook <iamacook@users.noreply.github.com>
Co-authored-by: Diogo Soares <diogo.lsoares@gmail.com>
Co-authored-by: Diogo Soares <32431609+DiogoSoaress@users.noreply.github.com>
2023-03-03 11:22:11 +01:00
Manuel GellfartandGitHub e383db710b fix: use new app deployment url (#1472)
* fix: use new app deployment url

* fix: remove outdated sections
2023-01-02 14:34:16 +01:00
katspaughandGitHub 73b09fc02e Chore: deploy HTML files w/o extension (#805)
* Chore: deploy HTML files w/o extension

* Update release docs

* staging = main

* Rm build from lint

* Rm prettier from precommit
2022-10-06 12:31:57 +02:00
katspaughandGitHub 8bb6bd9192 Docs: copy docs from safe-react (#579)
* Docs: copy docs from safe-react

* Update useTxQueue.ts
2022-09-20 11:40:22 +02:00
c314f5d0df Chore: contributing.md + code of conduct (#374)
* Chore: contributing.md + code of conduct

* Update wording in migration.md

* Update CONTRIBUTING.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* Update CONTRIBUTING.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* Update docs/code-style.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* Update docs/code-style.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* Update src/services/ls-migration/README.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* Update src/services/ls-migration/README.md

Co-authored-by: Aaron Cook <aaron@safe.global>

* (LS)

Co-authored-by: Aaron Cook <aaron@safe.global>
2022-08-18 14:53:09 +02:00