8.6 KiB
Client Wallet Access Design
Date: 2026-03-25 Status: Proposed
Goal
Add a client-centric UI that lets an operator choose which EVM wallets are visible to a given SDK client.
The mental model is:
For this SDK client, choose which wallets it can see.
This UI should live under the existing Clients area, not under Wallets, because the permission is being edited from the client's perspective.
Current Context
The current Flutter app has:
- A top-level dashboard with
Wallets,Clients, andAbout - A
Clientsscreen that currently acts as a registry/list ofSdkClientEntry - A
Walletsscreen that lists managed EVM wallets - An EVM grant creation flow that still manually asks for
Client ID
Relevant observations from the current codebase:
SdkClientEntryis already a richer admin-facing object thanWalletEntryWalletEntryis currently minimal and not suited to owning the relationship UI- The
Clientsscreen already presents expandable client rows, which makes it the most natural entry point for a details view
Chosen Approach
Use a dedicated client details screen.
From the Clients list, the operator opens one client and lands on a screen dedicated to that client. That screen includes a wallet access section that shows:
- Client identity and metadata
- Current wallet access selection
- A searchable/selectable list of available wallets
- Save feedback and error states
This is preferred over inline editing or a modal because it scales better when more capabilities are added later, such as:
- Search
- Bulk actions
- Explanatory copy
- Access summaries
- Future permission categories beyond wallet visibility
User Experience
Entry
The operator starts on the existing Clients screen.
Each client row gains a clear affordance to open details, for example:
- Tapping the row
- A trailing button such as
Manage access
The existing list remains the overview surface. Editing does not happen inline.
Client Details Screen
The screen is focused on a single client and should contain:
- A lightweight header with back navigation
- A client summary section
- A wallet access section
- Save/status feedback
The wallet access section is the core interaction:
- Show all available EVM wallets
- Show which wallets are currently accessible to this client
- Allow toggling access on/off
- Allow filtering/searching wallets when the list grows
- Show empty/loading/error states
Save Model
Use an explicit save action rather than auto-save.
Reasons:
- Permission changes are administrative and should feel deliberate
- Multiple checkbox changes can be staged together
- It creates a clear place for pending, success, and failure states
The screen should track:
- Original selection from the server
- Current local selection in the form
- Whether there are unsaved changes
Information Architecture
Navigation
Add a nested route under the dashboard clients area for client details.
Conceptually:
Clientsremains the list screenClient Detailsbecomes the edit/manage screen for one client
This keeps the current top-level tabs intact and avoids turning wallet access into a global dashboard concern.
Screen Ownership
Wallet visibility is owned by the client details screen, not by the wallets screen.
The wallets screen can remain focused on wallet inventory and wallet creation.
State Management
Use Riverpod.
State should be split by concern instead of managed in one large widget:
- Provider for the client list
- Provider for the wallet list
- Provider for the selected client details data
- Provider or notifier for wallet-access editing state
- Mutation/provider for saving wallet access changes
Recommended shape:
- One provider fetches the wallet inventory
- One provider fetches wallet access for a specific client
- One notifier owns the editable selection set for the client details form
- One mutation performs save and refreshes dependent providers
The editing provider should expose:
- Current selected wallet identifiers
- Original selected wallet identifiers
hasChangesisSaving- Validation or request error message when relevant
This keeps the UI declarative and prevents the screen widget from holding all state locally.
Data Model Assumptions
The UI assumes there is or will be a backend/API surface equivalent to:
- List SDK clients
- List EVM wallets
- Read wallet access entries for one client
- Replace or update wallet access entries for one client
The screen should work with wallet identifiers that are stable from the backend perspective. If the backend only exposes positional IDs today, that should be normalized before binding the UI tightly to list index order.
This is important because the current grant creation screen derives walletId from list position, which is not a robust long-term UI contract.
Layout and Styling Constraints
Implementation must follow these constraints:
- Use Riverpod for screen state and mutations
- Do not hardcode widths and heights
- Prefer layout driven by padding, constraints, flex, wrapping, and intrinsic content
- Keep widgets granular; a widget should not exceed roughly 50 lines
- Do not place all client-details widgets into a single file
- Create a dedicated widgets folder for the client details screen
- Reuse existing UI patterns and helper widgets where it is reasonable, but do not force reuse when it harms clarity
Recommended implementation structure:
lib/screens/dashboard/clients/details/lib/screens/dashboard/clients/details/client_details.dartlib/screens/dashboard/clients/details/widgets/...
Widget Decomposition
The client details feature should be composed from small widgets with single responsibilities.
Suggested widget split:
ClientDetailsScreenClientDetailsScaffoldClientDetailsHeaderClientSummaryCardWalletAccessSectionWalletAccessSearchFieldWalletAccessListWalletAccessListItemWalletAccessEmptyStateWalletAccessErrorStateWalletAccessSaveBar
If useful, existing generic state panels or cards from the current screens can be adapted or extracted, but only where that reduces duplication without making the code harder to follow.
Interaction Details
Client Summary
Display the client's:
- Name
- ID
- Version
- Description
- Public key summary
- Registration date
This gives the operator confidence that they are editing the intended client.
Wallet Access List
Each wallet item should show enough identity to make selection safe:
- Human-readable label if one exists in the backend later
- Otherwise the wallet address
- Optional secondary metadata if available later
Each item should have a clear selected/unselected control, most likely a checkbox.
Unsaved Changes
When the current selection differs from the original selection:
- Show a save bar or action row
- Enable
Save - Optionally show
ResetorDiscard
When there are no changes:
- Save action is disabled or visually deemphasized
Loading and Errors
The screen should independently handle:
- Client not found
- Wallet list unavailable
- Wallet access unavailable
- Save failure
- Empty wallet inventory
These states should be explicit in the UI rather than collapsed into a blank screen.
Reuse Guidance
Reasonable reuse candidates from the current codebase:
- Existing color/theme primitives
- Existing state/empty panels if they can be extracted cleanly
- Existing wallet formatting helpers, if they are generalized
Reuse should not be prioritized over good boundaries. If the existing widget is too coupled to another screen, create a new focused widget instead.
Testing Strategy
Plan for widget and provider-level coverage.
At minimum, implementation should be testable for:
- Rendering client summary
- Rendering preselected wallet access
- Toggling wallet selection
- Dirty state detection
- Save success refresh flow
- Save failure preserving local edits
- Empty/loading/error states
Given the current test directory is empty, this feature is a good place to establish basic screen/provider tests rather than relying only on manual verification.
Out of Scope
The following are not required for the first version unless backend requirements force them:
- Cross-client bulk editing
- Wallet-side permission management
- Audit history UI
- Role templates
- Non-EVM asset permissions
Recommendation Summary
Implement wallet access management as a dedicated client details screen under Clients.
This gives the cleanest product model:
Clientsanswers "who is this app/client?"Wallet accessanswers "what wallets can it see?"
It also gives the best technical path for Riverpod-managed state, granular widget decomposition, and future expansion without crowding the existing client list UI.