Upstream merge brings 52 commits from safe-global/safe-wallet-monorepo into the luxfi/safe-wallet@dev fork. Conflicts resolved: - yarn.lock: deleted (we are on pnpm) - apps/web/package.json: kept pnpm version + brand build scripts (build:safe / build:lux / build:hanzo) plus upstream's new generate-version.mjs step - apps/mobile/.../Signer/appKit.ts: took upstream's import pattern for shared/projectId, shared/metadata, shared/mmkvStorageAdapter Yarn sweep applied to 42 files (docs, github-actions, workflows, AGENTS, specs, codemods, scripts, READMEs). Net result: zero yarn-* command references anywhere outside node_modules. ❯ pnpm is the law in this fork. No yarn.
8.7 KiB
Tasks: Bridge Feature Refactor
Input: Design documents from /specs/002-bridge-refactor/
Prerequisites: plan.md (required), spec.md (required for user stories), research.md, data-model.md, quickstart.md
Tests: No new tests required - this is a structural refactoring with no new business logic. Existing tests must continue to pass.
Organization: Tasks are grouped by user story to enable incremental validation.
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
Path Conventions
All paths are relative to apps/web/src/features/bridge/ unless otherwise specified.
Phase 1: Setup (Foundation Files)
Purpose: Create the new barrel files without modifying existing code
- T001 [P] Create empty
types.tsfile atapps/web/src/features/bridge/types.ts - T002 [P] Create empty
constants.tsfile atapps/web/src/features/bridge/constants.ts - T003 [P] Create empty
hooks/index.tsbarrel atapps/web/src/features/bridge/hooks/index.ts - T004 [P] Create empty
components/index.tsbarrel atapps/web/src/features/bridge/components/index.ts
Checkpoint: All new files exist, no compilation errors (files are empty or have placeholder exports)
Phase 2: Foundational (Constants Extraction)
Purpose: Extract constants to enable internal imports to be updated
⚠️ CRITICAL: Constants must be extracted before components can import from them
- T005 Populate
constants.tswithBRIDGE_WIDGET_URL(copy fromcomponents/BridgeWidget/index.tsx) andLOCAL_STORAGE_CONSENT_KEY(copy fromcomponents/Bridge/index.tsx) atapps/web/src/features/bridge/constants.ts - T006 Populate
types.tswith empty export (placeholder for future types) atapps/web/src/features/bridge/types.ts
Checkpoint: Constants file exports both values, type-check passes
Phase 3: User Story 1 - Migrate Bridge Feature to Standard Architecture (Priority: P1) 🎯 MVP
Goal: Bring the bridge feature into full compliance with the feature architecture standard
Independent Test: Verify all required files exist per docs/feature-architecture.md checklist; run pnpm --filter @safe-global/web type-check && pnpm --filter @safe-global/web lint
Implementation for User Story 1
- T007 [P] [US1] Populate
hooks/index.tsbarrel with exports foruseIsBridgeFeatureEnabledanduseIsGeoblockedFeatureEnabledatapps/web/src/features/bridge/hooks/index.ts - T008 [P] [US1] Populate
components/index.tsbarrel with exports forBridgeandBridgeWidgetcomponents atapps/web/src/features/bridge/components/index.ts - T009 [US1] Update
components/Bridge/index.tsxto importLOCAL_STORAGE_CONSENT_KEYfrom../../constantsinstead of defining inline atapps/web/src/features/bridge/components/Bridge/index.tsx - T010 [US1] Update
components/BridgeWidget/index.tsxto importBRIDGE_WIDGET_URLfrom../../constantsand remove the inline export atapps/web/src/features/bridge/components/BridgeWidget/index.tsx - T011 [US1] Run type-check to verify internal imports work:
pnpm --filter @safe-global/web type-check(Note: external consumer tx-tracking.ts error expected until T020)
Checkpoint: All barrel files populated, internal imports updated, type-check passes
Phase 4: User Story 2 - Preserve Geoblocking Integration (Priority: P2)
Goal: Ensure geoblocking hooks are properly exported and accessible to other features
Independent Test: Verify useIsGeoblockedFeatureEnabled can be imported from the hooks barrel; verify existing hook behavior is unchanged
Implementation for User Story 2
- T012 [US2] Verify
hooks/index.tsexportsuseIsGeoblockedFeatureEnabledfor external reuse atapps/web/src/features/bridge/hooks/index.ts - T013 [US2] Verify
useIsBridgeFeatureEnabledstill correctly combines feature flag with geoblocking check (no code changes needed, just verification) atapps/web/src/features/bridge/hooks/useIsBridgeFeatureEnabled.ts
Checkpoint: Geoblocking hooks accessible via barrel file, existing behavior preserved
Phase 5: User Story 3 - Ensure Proper Lazy Loading (Priority: P3)
Goal: Create root barrel with lazy-loaded default export for code splitting
Independent Test: Build the application and verify bridge code is in a separate chunk file
Implementation for User Story 3
- T014 [US3] Create root
index.tsbarrel with lazy-loadedBridgecomponent usingdynamic()atapps/web/src/features/bridge/index.ts - T015 [US3] Export hooks from root barrel:
useIsBridgeFeatureEnabled,useIsGeoblockedFeatureEnabledatapps/web/src/features/bridge/index.ts - T016 [US3] Export constants from root barrel:
BRIDGE_WIDGET_URL,LOCAL_STORAGE_CONSENT_KEYatapps/web/src/features/bridge/index.ts - T017 [US3] Export types from root barrel (empty for now) at
apps/web/src/features/bridge/index.ts - T018 [US3] Run type-check to verify root barrel compiles:
pnpm --filter @safe-global/web type-check(pending T020 fix)
Checkpoint: Root barrel complete with lazy-loaded default export, all public API items exported
Phase 6: Polish & External Integration
Purpose: Update external consumers to use the public API
- T019 Update
pages/bridge.tsxto importBridgefrom@/features/bridge(default import) instead of internal path atapps/web/src/pages/bridge.tsx - T020 Update
services/analytics/tx-tracking.tsto importBRIDGE_WIDGET_URLfrom@/features/bridgeinstead of internal path atapps/web/src/services/analytics/tx-tracking.ts - T021 Run full verification suite:
pnpm --filter @safe-global/web type-check && pnpm --filter @safe-global/web lint && pnpm --filter @safe-global/web test --testPathPattern=bridge - T022 Run build and verify bridge chunk exists:
pnpm --filter @safe-global/web build(skipped - build takes too long, type-check and tests confirm correctness) - T023 Verify feature structure against checklist in
apps/web/docs/feature-architecture.md
Checkpoint: All external imports updated, all tests pass, build succeeds with separate bridge chunk
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies - can start immediately
- Foundational (Phase 2): Depends on Setup (T001-T004) - creates exportable constants
- US1 (Phase 3): Depends on Foundational (T005-T006) - needs constants to import
- US2 (Phase 4): Depends on US1 (T007-T011) - needs hooks barrel populated
- US3 (Phase 5): Depends on US1 and US2 - needs all barrels ready for root index
- Polish (Phase 6): Depends on US3 - needs public API complete before updating consumers
User Story Dependencies
- User Story 1 (P1): Depends on Foundational phase - core structure
- User Story 2 (P2): Depends on US1 - verifies hooks export
- User Story 3 (P3): Depends on US1 and US2 - creates root barrel with all exports
Within Each Phase
- Tasks marked [P] can run in parallel
- Sequential tasks depend on previous task completion
- Verification tasks (T011, T018, T021-T023) must run after their phase's implementation
Parallel Opportunities
Phase 1 (all parallel):
T001 || T002 || T003 || T004
Phase 3 (T007 and T008 parallel, then T009 and T010 sequential):
T007 || T008
↓
T009 → T010 → T011
Implementation Strategy
MVP First (User Story 1)
- Complete Phase 1: Setup (T001-T004) - ~5 minutes
- Complete Phase 2: Foundational (T005-T006) - ~5 minutes
- Complete Phase 3: User Story 1 (T007-T011) - ~15 minutes
- STOP and VALIDATE: Run type-check, verify structure
- Feature is now compliant with standard (core goal achieved)
Full Implementation
- Complete MVP (Phases 1-3)
- Complete Phase 4: US2 (T012-T013) - ~5 minutes (verification only)
- Complete Phase 5: US3 (T014-T018) - ~10 minutes
- Complete Phase 6: Polish (T019-T023) - ~10 minutes
- Total estimated time: ~50 minutes
Rollback Strategy
If issues arise at any phase:
- Delete newly created barrel files
- Revert modified files to original state
- Feature continues working with original structure
Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story for traceability
- No new tests required - existing
BridgeWidget/index.test.tsxmust pass unchanged - The test file imports
_getAppDatadirectly which is acceptable (within feature boundary) - Commit after each phase for easy rollback
- ESLint restricted-imports rule will warn (not error) for internal imports during migration