MidnightSdkProvider

@Singleton
class MidnightSdkProvider @Inject constructor(walletSeedSource: WalletSeedSource, sdkFactory: MidnightSdkFactory)

Process-wide owner of the single live MidnightSdk instance.

Why this exists. Before this, every consumer that needed a wallet built its own SDK — the wallet panel and BBoard each constructed one, so the app opened two indexer WebSockets, replayed zswap from genesis twice, and ran two dust DBs. Two instances of the same wallet on the same seed and network was never intended; it was duplication, not redundancy. This provider holds exactly one SDK and hands it to all consumers.

Ownership model — one authority, many followers.

  • The config authority (the wallet panel — the only UI with the network / proving-mode / proof-server toggles) calls ensureSdk with a full WalletConfig. That is the sole place config changes enter the system, which is what makes activeConfig a single source of truth.

  • Followers (BBoard's contract ops, Kicks's match manager) don't own config. They call awaitSdk for the shared handle and read activeConfig for "which chain am I on". They never pass a competing config, so the provider never thrashes between two configs.

Lifecycle. The SDK is a process-singleton, not view-model-scoped. It survives activity recreation (rotation) — a net win, since rebuilding means a fresh biometric prompt + resync. Teardown is therefore explicit via close (logout / wallet reset). No caller invokes close today; it's the seam a future session-auto-lock (idle timeout) will use.

See also

for the construction seam this delegates to.

Constructors

Link copied to clipboard
@Inject
constructor(walletSeedSource: WalletSeedSource, sdkFactory: MidnightSdkFactory)

Properties

Link copied to clipboard
val activeConfig: StateFlow<WalletConfig?>

The config the live sdk was built with — the canonical answer to "which network / proving mode is the wallet on". Null when no SDK exists.

Link copied to clipboard
val sdk: StateFlow<MidnightSdk?>

The live SDK, or null before the first build / after close.

Functions

Link copied to clipboard
suspend fun awaitSdk(): MidnightSdk

Suspend until an SDK exists, then return it. For followers that consume the shared SDK but don't drive config (BBoard contract ops). If the authority never builds (e.g. the panel is gated on an un-forged sigil), this waits — by design, since a follower has no wallet to act on until the authority bootstraps one.

Link copied to clipboard
fun close()

Tear down the live SDK and clear state (logout / wallet reset).

Link copied to clipboard
suspend fun ensureSdk(activity: FragmentActivity, config: WalletConfig): MidnightSdk

Build the SDK for config, or reuse the live one if config is unchanged. On a config change, the previous SDK is closed (its subscriptions cancelled) before the new one is built.