-
Notifications
You must be signed in to change notification settings - Fork 54
test(swift-sdk): add testnet identity-discovery UI test #3560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v3.1-dev
Are you sure you want to change the base?
Changes from 21 commits
03af8e2
b3c85a2
7c0ae94
c08f9fa
52312a2
e8eb123
4e4cf1a
296d966
3823ee4
33b6f3c
a228c04
983f89c
4801f03
0e38b24
92cddcd
8cfad23
be5f3fa
a8ada7b
d3503c8
2624335
4fe6259
19c4c49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,12 +9,27 @@ class AppState: ObservableObject { | |
| @Published var showError = false | ||
| @Published var errorMessage = "" | ||
|
|
||
| /// `true` from the moment a network change is requested until the | ||
| /// new SDK is bound. Spans the full async cycle (didSet → Task → | ||
| /// `switchNetwork` → `sdk = newSDK`), so consumers can wait on it | ||
| /// as a real readiness signal. UI bindings should treat | ||
| /// `appState.sdk != nil && !isSwitchingNetwork` as "connected on | ||
| /// the current network" — `appState.sdk != nil` alone is true even | ||
| /// while `switchNetwork` is still tearing down the previous SDK. | ||
| @Published var isSwitchingNetwork: Bool = false | ||
|
|
||
| /// Monotonic request id for in-flight switches. If two switches | ||
| /// overlap (user taps mainnet → testnet before the first lands), the | ||
| /// earlier task's completion would otherwise clear `isSwitchingNetwork` | ||
| /// while the later switch is still running. Each new request bumps | ||
| /// this counter and the spawned task only clears the flag when its | ||
| /// captured id still matches. | ||
| private var networkSwitchRequestID: UInt64 = 0 | ||
|
|
||
| @Published var currentNetwork: Network { | ||
| didSet { | ||
| UserDefaults.standard.set(Int(currentNetwork.rawValue), forKey: "currentNetwork") | ||
| Task { | ||
| await switchNetwork(to: currentNetwork) | ||
| } | ||
| UserDefaults.standard.set(currentNetwork.rawValue, forKey: "currentNetwork") | ||
| beginNetworkSwitch() | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -27,10 +42,32 @@ class AppState: ObservableObject { | |
| UserDefaults.standard.set(useDockerSetup, forKey: "useLocalhostPlatform") | ||
| UserDefaults.standard.set(useDockerSetup, forKey: "useLocalhostCore") | ||
| UserDefaults.standard.set(useDockerSetup, forKey: "useLocalhost") | ||
| Task { await switchNetwork(to: currentNetwork) } | ||
| beginNetworkSwitch() | ||
| } | ||
| } | ||
|
Comment on lines
53
to
58
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Blocking: Carried-forward prior finding (STILL VALID): Docker-setup toggle leaves the cached regtest wallet manager bound to the previous SDK Prior finding from review at 4fe6259 — STILL VALID at 19c4c49. Re-validated end-to-end against the current head.
The stale-cache check in The correct precedent already exists in the codebase: the devnet-quorum-edit path in OptionsView.swift:290-330 explicitly re-calls source: ['claude'] |
||
|
|
||
| /// Bumps `networkSwitchRequestID`, raises `isSwitchingNetwork`, and | ||
| /// spawns the SDK-rebuild task. Only the task that owns the latest | ||
| /// request id may lower `isSwitchingNetwork` again — overlapping | ||
| /// switches' earlier tasks no-op on completion. | ||
| private func beginNetworkSwitch() { | ||
| networkSwitchRequestID &+= 1 | ||
| let requestID = networkSwitchRequestID | ||
| isSwitchingNetwork = true | ||
| Task { | ||
| await switchNetwork(to: currentNetwork, requestID: requestID) | ||
| if requestID == networkSwitchRequestID { | ||
| isSwitchingNetwork = false | ||
| } | ||
| } | ||
| } | ||
|
llbartekll marked this conversation as resolved.
|
||
|
|
||
| /// True if `token` is still the most recent network-switch request. | ||
| /// Stale tasks bail out before mutating shared state. | ||
| private func isCurrent(_ token: UInt64) -> Bool { | ||
| token == networkSwitchRequestID | ||
| } | ||
|
|
||
| // Identity-key signing is performed per-flow via a fresh | ||
| // `KeychainSigner` constructed from the active `ModelContainer` | ||
| // (see `CreateIdentityView.submit()`). `AppState` no longer holds | ||
|
|
@@ -101,8 +138,9 @@ class AppState: ObservableObject { | |
| showError = true | ||
| } | ||
|
|
||
| func switchNetwork(to network: Network) async { | ||
| func switchNetwork(to network: Network, requestID: UInt64) async { | ||
| guard let modelContext = modelContext else { return } | ||
| guard isCurrent(requestID) else { return } | ||
|
|
||
| // Identities, contracts, documents, and token balances are | ||
| // scoped per-network inside SwiftData. `@Query` consumers | ||
|
|
@@ -118,13 +156,16 @@ class AppState: ObservableObject { | |
|
|
||
| // Create new SDK instance for the network | ||
| let newSDK = try SDK(network: network) | ||
| guard isCurrent(requestID) else { return } | ||
| sdk = newSDK | ||
|
|
||
| // Load known contracts into the SDK's trusted provider | ||
| await loadKnownContractsIntoSDK(sdk: newSDK, modelContext: modelContext) | ||
| guard isCurrent(requestID) else { return } | ||
|
|
||
| isLoading = false | ||
| } catch { | ||
| guard isCurrent(requestID) else { return } | ||
| sdk = nil | ||
| showError(message: "Failed to switch network: \(error.localizedDescription)") | ||
| NSLog("❌ AppState.switchNetwork: \(error)") | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.