Fix SignerPicker not showing in SmartWalletsDemo#92
Merged
tomas-martins-crossmint merged 3 commits intoMay 27, 2026
Conversation
Move delegatedSigners into AppState so it's loaded before any view renders, removing the dependency on .task firing on an empty Section. Auto-selection of the first signer is preserved in loadSigners(). Show picker whenever at least one selectable signer exists (not just when count > 1). Fix locator fallback to signer field for API responses that use either field.
Contributor
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
Examples/SmartWalletsDemo/SmartWalletsDemo/Playground/AppState.swift:95-110
**`createWallet` skips `loadSigners()`, leaving the signer unselected**
After wallet creation, `loadSigners()` is never called, so `delegatedSigners` stays `[]` and `selectSigner` is never invoked. The `SignerPicker` binding falls back to `opts.first?.id` visually (the recovery locator), but `wallet.useSigner(config)` is never called on the underlying SDK — meaning wallet operations after creation may run without an explicitly configured signer. Both `loadWallet` and `switchChain` call `await loadSigners()` after `fetchBalance()`, but `createWallet` does not, creating an inconsistent state.
### Issue 2 of 2
Examples/SmartWalletsDemo/SmartWalletsDemo/Playground/Signers/SignersView.swift:34-44
**Inconsistency between `SignerPicker` and `SignersView` for signers where `locator` is nil**
`SignerPicker` now uses `signer.locator ?? signer.signer` so a signer where only the `signer` field is populated will appear as a selectable option in the picker. However, `SignersView` still uses `id: \.locator` for `ForEach` and guards `if let locator = signer.locator` — meaning that same signer won't be rendered in the Signers management screen and can't be removed. If the API does return entries with `locator == nil`, those signers end up in an inconsistent state: selectable but not removable.
Reviews (1): Last reviewed commit: "Fix SignerPicker not showing in SmartWal..." | Re-trigger Greptile |
…sistency Call loadSigners() in createWallet so delegatedSigners is populated and the first signer is auto-selected immediately after creation, matching the behavior of loadWallet and switchChain. Precompute signerItems in SignersView using locator ?? signer so delegated signers where only the signer field is populated are displayed and removable, consistent with how SignerPicker already handles them.
Contributor
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
Examples/SmartWalletsDemo/SmartWalletsDemo/Playground/Signers/SignersView.swift:14-26
The `signerItems` computed property is sandwiched between `@State` property declarations (`isLoadingSigners` above and `alertTitle`/`alertMessage`/`showAlert` below), making the property group harder to scan. Consider grouping all stored `@State` properties together and placing computed properties in a separate section.
```suggestion
@State private var isLoadingSigners = false
@State private var alertTitle = ""
@State private var alertMessage = ""
@State private var showAlert = false
private var isRemovingSigner: Bool { removingSignerLocator != nil }
private var signerItems: [(locator: String, model: WalletDelegatedSignerConfigApiModel)] {
appState.delegatedSigners.compactMap { signer in
guard let locator = signer.locator ?? signer.signer else { return nil }
return (locator: locator, model: signer)
}
}
```
Reviews (2): Last reviewed commit: "Address signer state gaps after wallet c..." | Re-trigger Greptile |
Contributor
|
Reviews (3): Last reviewed commit: "Group @State properties before computed ..." | Re-trigger Greptile |
afeight
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SignerPicker was invisible even when the wallet had selectable signers. The picker used a
.taskattached to aGroup/Sectionthat starts empty, and SwiftUI doesn't fire.taskon an empty section — so by the timewallet.signers()returned, the layout had already settled and the section never appeared.Changes
AppStatenow ownsdelegatedSignersand exposes aloadSigners()method that callswallet?.signers(). It's called afterfetchBalance()in bothloadWalletandswitchChain(for cached wallets), so signers are always populated before any view renders.loadSigners()also restores the auto-selection behavior from the old.task: if no signer is currently selected, it picks the first selectable locator and callsselectSigner.SignerPickerdrops the local@State var delegatedSignersand the.taskentirely, reading fromappState.delegatedSignersinstead. Picker now shows whenever there's at least one selectable signer (wascount > 1). Locator fallback fixed tosigner.locator ?? signer.signersince the API can return the locator in either field.SignersView.loadSigners()delegates toappState.loadSigners()and reads fromappState.delegatedSignersto stay in sync.