Skip to content

fix(sdk): wallet-flow network fixes for SwiftExampleApp - #3772

Merged
QuantumExplorer merged 18 commits into
v3.1-devfrom
fix/swift-wallet-flow-network-fixes
Jun 9, 2026
Merged

fix(sdk): wallet-flow network fixes for SwiftExampleApp#3772
QuantumExplorer merged 18 commits into
v3.1-devfrom
fix/swift-wallet-flow-network-fixes

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented May 31, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

A set of wallet-flow fixes in the iOS SwiftExampleApp / swift-sdk for operating across multiple networks. The same mnemonic can now live on several networks, and the create / rescan / add-to-network flows behave correctly when the target network isn't the currently-active one.

Bugs fixed:

  1. Mainnet/testnet wallet creation silently failed. The devnet-only platformQuorumURL override was applied to every network, leaking a non-https http://… quorum URL into mainnet/testnet SDK construction. Rust's trusted context provider rejects a non-https custom quorum URL on those networks, so the build failed and no wallet was created.
  2. Create dialog ignored the ticked network. Ticking e.g. "Mainnet" while on devnet created a devnet wallet instead — only the first/active network was used.
  3. No feedback on create failure. The error alert is bound to CreateWalletView, but the pushed SeedBackupView stayed on top with its submit button stuck disabled — the user was stranded with no visible error.
  4. Per-network "+" add-to-network did nothing. The button in Wallet Info didn't actually add an existing wallet to another network.
  5. Re-scan for Identities showed wallets from all networks. The picker used an unfiltered @Query, listing every wallet across every network instead of just the active-network ones.

What was done?

Per-network persistence infrastructure

  • PersistentWallet.swift — make rows unique per (walletId, network) and add predicate(walletId:) / predicate(walletId:network:) helpers, so the same mnemonic can coexist across networks without colliding.
  • PlatformWalletPersistenceHandler.swift / PlatformWalletManager.swift — scope persister wallet lookups to the manager's network, so each per-network manager restores only its own rows.

Create flow

  • CreateWalletView.swift — create the wallet in every ticked network via WalletManagerStore.backgroundManager(for:) (each network has its own network-locked Rust manager); walletId is network-independent, so the Keychain mnemonic + metadata are written once and isImported is stamped on every per-network row. On failure, pop the pushed backup screen so the error alert becomes visible.
  • SDK.swift — gate the platformQuorumURL (and DAPI address) override behind useOverrideAddresses (regtest/devnet or opt-in docker). Mainnet/testnet now use the SDK's automatic canonical quorum endpoints.

Add-to-network / identities / rescan

  • WalletDetailView.swift — implement the per-network "+" add-to-network action.
  • IdentitiesContentView.swift — take an explicit network and scope the identities @Query to it; IdentitiesView.swift passes the active network; ContentView.swift threads the active network through.
  • SearchWalletsForIdentitiesView.swift — add platformState, query all wallets, and filter to the active network via a computed property (mirrors WalletsContentView@Query can't reference a runtime env-object value at property-init time). The rescan sheet re-injects platformState.

All changes are Swift-side only (persist / load / bridge) — no Rust/FFI changes, no protocol changes.

How Has This Been Tested?

Verified on the booted iOS simulator (iPhone 17 Pro) against the live SwiftData store:

  • Create routes to ticked network: a testnet-only create while on devnet produced exactly one networkRaw=1 row and no devnet fallback row.
  • Add-to-network: the per-network "+" produced a new per-network row + UI checkmark for the target network.
  • Rescan network filter: with currentNetwork = mainnet and 9 persisted wallet rows across 4 networks (mainnet ×1, testnet ×3, devnet ×2, regtest ×3), the Re-scan for Identities picker now lists only the single mainnet wallet — count dropped 9 → 1, matching the active-network set exactly.
  • Quorum override: confirmed via boot console that mainnet SDK construction logs no DAPI addresses provided, using defaults for network / Mainnet (no leaked devnet http://…:8080 quorum URL), while the devnet manager still uses its caller-provided quorum URL.
  • Create-failure UX: verified the backup screen pops on failure so the error alert is reachable.

Note: this PR does not fix a separate, pre-existing crash in the external dash-spv dependency (SegmentedStorage::get_items() panics on segments with a non-zero first_valid_offset), which causes the Core Sync "Start" button to appear to do nothing on mainnet. Filed upstream at dashpay/rust-dashcore#792.

Breaking Changes

None. Swift SDK / example-app behavior only; no consensus or protocol changes.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Multi-network wallet creation persists wallets per network and saves mnemonics per network.
    • UI respects selected network across Identities, search, and Wallet detail.
    • Wallet detail can enable a wallet on additional networks.
  • Bug Fixes

    • Wallet IDs can repeat across networks (now treated as network-scoped).
    • Safer deletion: keychain mnemonic/metadata and cached data are removed only when the last network instance is deleted.
    • Avoids leaking dev/test quorum endpoints into production.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants