You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Remove the global ExtraDependencies contract from thunk implementations. Every thunk should expose only the state and injected dependencies it actually consumes, so unit tests can construct minimal stores without the full global dependency graph or as any casts.
The end state is that ExtraDependencies is not used by thunks, tests, feature middleware, or feature packages. It may remain only at composition roots while the application store is assembled. Dependency-bearing thunks must declare a named <ThunkName>Deps type directly above the thunk and compose nested thunk contracts with &. Dependency-free thunks keep the explicit void third generic.
Inventory baseline
A scan of develop currently finds approximately 345 createThunk call sites:
suite-common/wallet-core: 106
suite-common/trading: 83
packages/suite: 43
suite-common/walletconnect: 16
suite-common/connect-popup: 9
Suite Native packages: approximately 60
Remaining Suite and Suite Common feature packages: approximately 28
There are also explicit ExtraDependencies annotations in vanilla thunks, middleware APIs, test mocks, and store setup. Counts should be refreshed after the prerequisite PRs land.
Conventions
Use type <ThunkName>Deps = ... directly above every dependency-bearing thunk.
Compose reusable service dependency contracts and child-thunk contracts with intersections (&).
Use direct state contracts such as DeviceRootState; do not infer state with Parameters<typeof selector>[0].
Declare a named <ThunkName>State where a thunk reads state.
Use the explicit third generic void when a thunk needs neither state nor injected dependencies.
Do not use ExtraDependencies, CustomThunkAPI, as any, or full dependency mocks as a shortcut.
Parent thunks must include the state/dependency contracts of child thunks they dispatch.
Update tests to pass only the state slices and dependencies required by the thunk under test.
Finish and land the first broad RTK conversion batch in refactor(redux): narrow RTK thunk dependencies #30767, including the explicit-void behavior and the app-level dispatch compatibility exposed by the aggregate Suite type-check.
Conversion plan
Vanilla thunks
Convert remaining desktop Suite vanilla thunks in packages/suite/src/actions: staking (Cardano, Ethereum, Solana), stake orchestration, protocol/suite leftovers, modal callbacks, and any newly added call sites.
Convert remaining suite/* vanilla thunks: metadata labeling/provider flows, metadata migration modal dispatch, device flows, and any desktop-update/receive leftovers after refactor(suite): narrow vanilla thunk dependencies #30733.
Convert any remaining Suite Common and Suite Native vanilla thunks; replace explicit global dispatch/get-extra annotations with local state and <ThunkName>Deps contracts.
RTK thunks — Suite Common
Convert wallet-core foundation: accounts, discovery, device lifecycle, blockchain, explorer, settings, UI events, fiat rates, and token management.
Convert WalletConnect and adapters: session lifecycle plus Bitcoin, Ethereum, Solana, Stellar, and Tron request thunks.
Convert Connect integration packages: connect-init, connect-popup, and all nested picker, permission, verification, and cancellation flows.
Convert remaining small Suite Common packages: firmware, authenticity, message-system, token-definitions, toast notifications, THP, feedback, geolocation, and future call sites.
RTK thunks — Desktop Suite
Convert desktop Bluetooth thunks and storage-related child dispatch chains.
Convert Suite shell/device/settings/router/recovery/metadata/labeling thunks, including application reset, auto-eject, device forget, language, wallet selection, and navigation.
Convert wallet send and transaction UI thunks: form drafts, metadata labels, signing/pushing, graph updates, exports, wrap/unwrap, and Tron cancellation.
Convert desktop trading wrapper thunks for buy, exchange, and sell.
Convert Native earn and trading packages: module-earn, module-trading, trading-state, and their middleware/tests.
Convert remaining Native feature packages and refresh the inventory to include thunks added while this epic is active.
Infrastructure, middleware, and tests
Make app-level dispatch/store typing accept thunks with narrower state/extra contracts without losing .unwrap(), .abort(), action metadata, or payload inference in desktop and Native consumers.
Make createSingleInstanceThunk and any other thunk factories support the same named selective contracts and explicit-void behavior.
Parameterize middleware helpers over their actual dependency contracts; remove ExtraDependencies from feature middleware and middleware tests.
Split the global dependency mocks into small reusable dependency fixtures and migrate tests away from extraDependenciesCommonMock, desktop/native full mocks, Partial<ExtraDependencies>, and casts.
Add/adjust type tests proving omitted RTK config remains backward compatible during migration, explicit void means no dependencies, named selective contracts reject undeclared access, and parent/child composition remains sound.
After every createThunk call site has an explicit state/dependency contract, remove the legacy DefaultThunkAPI/CustomThunkAPI fallback. An omitted third generic must mean no state or injected dependencies (extra: Record<never, never>), so accessing injected dependencies requires an explicit { extra: <ThunkName>Deps } contract.
Add ESLint enforcement that production thunk implementations may not import or reference the global ExtraDependencies or CustomThunkAPI; allow only explicitly documented composition-root/store files.
Add ESLint enforcement for thunk contracts: every dependency-bearing vanilla or RTK thunk must use a named <ThunkName>Deps type declared directly above it; dependency-free RTK thunks must use explicit void. Reject inline dependency object types and omitted third generics once migration is complete.
Document the thunk dependency/state conventions and the approved composition-root allowlist in the Redux contribution guidance.
Final audit: verify ExtraDependencies from suite-common/redux-utils is unused everywhere except the minimal desktop/Native composition roots, remove obsolete global mocks/types where possible, run repository-wide type-check/lint/tests, and ensure ESLint prevents regressions.
Goal
Remove the global
ExtraDependenciescontract from thunk implementations. Every thunk should expose only the state and injected dependencies it actually consumes, so unit tests can construct minimal stores without the full global dependency graph oras anycasts.The end state is that
ExtraDependenciesis not used by thunks, tests, feature middleware, or feature packages. It may remain only at composition roots while the application store is assembled. Dependency-bearing thunks must declare a named<ThunkName>Depstype directly above the thunk and compose nested thunk contracts with&. Dependency-free thunks keep the explicitvoidthird generic.Inventory baseline
A scan of
developcurrently finds approximately 345createThunkcall sites:suite-common/wallet-core: 106suite-common/trading: 83packages/suite: 43suite-common/walletconnect: 16suite-common/connect-popup: 9There are also explicit
ExtraDependenciesannotations in vanilla thunks, middleware APIs, test mocks, and store setup. Counts should be refreshed after the prerequisite PRs land.Conventions
type <ThunkName>Deps = ...directly above every dependency-bearing thunk.&).DeviceRootState; do not infer state withParameters<typeof selector>[0].<ThunkName>Statewhere a thunk reads state.voidwhen a thunk needs neither state nor injected dependencies.ExtraDependencies,CustomThunkAPI,as any, or full dependency mocks as a shortcut.Work already implemented / in progress
handleCoinProtocolUri).createThunkto override the default state/extra contract and convertbackupDeviceThunkin refactor(redux): support selective thunk dependencies #30677.voidbehavior and the app-level dispatch compatibility exposed by the aggregate Suite type-check.Conversion plan
Vanilla thunks
packages/suite/src/actions: staking (Cardano, Ethereum, Solana), stake orchestration, protocol/suite leftovers, modal callbacks, and any newly added call sites.suite/*vanilla thunks: metadata labeling/provider flows, metadata migration modal dispatch, device flows, and any desktop-update/receive leftovers after refactor(suite): narrow vanilla thunk dependencies #30733.<ThunkName>Depscontracts.RTK thunks — Suite Common
suite-common/tradingbuy and shared flows: initial data, address/payment request creation, nonce/refund/purchase helpers, trade watching, and verification.suite-common/tradingexchange flows: quote selection, approval, DEX prefetch/watch/sign/send, and exchange request/confirmation orchestration.suite-common/tradingsell flows: quote selection, request handling, confirmation, signing, sending, and trade watching.connect-init,connect-popup, and all nested picker, permission, verification, and cancellation flows.RTK thunks — Desktop Suite
RTK thunks — Suite Native
Infrastructure, middleware, and tests
.unwrap(),.abort(), action metadata, or payload inference in desktop and Native consumers.createSingleInstanceThunkand any other thunk factories support the same named selective contracts and explicit-voidbehavior.ExtraDependenciesfrom feature middleware and middleware tests.extraDependenciesCommonMock, desktop/native full mocks,Partial<ExtraDependencies>, and casts.voidmeans no dependencies, named selective contracts reject undeclared access, and parent/child composition remains sound.createThunkcall site has an explicit state/dependency contract, remove the legacyDefaultThunkAPI/CustomThunkAPIfallback. An omitted third generic must mean no state or injected dependencies (extra: Record<never, never>), so accessing injected dependencies requires an explicit{ extra: <ThunkName>Deps }contract.ExtraDependenciesorCustomThunkAPI; allow only explicitly documented composition-root/store files.<ThunkName>Depstype declared directly above it; dependency-free RTK thunks must use explicitvoid. Reject inline dependency object types and omitted third generics once migration is complete.ExtraDependenciesfromsuite-common/redux-utilsis unused everywhere except the minimal desktop/Native composition roots, remove obsolete global mocks/types where possible, run repository-wide type-check/lint/tests, and ensure ESLint prevents regressions.