> For AI agents: the documentation index is at https://sdk.nimbusprivacy.xyz/llms.txt, and every page is available as Markdown at its URL with .md appended.

# Changelog (/resources/changelog)

The SDK has no released version yet, so it has no `CHANGELOG.md`. This page lists every change
waiting for the next version, newest first. It is built from the repository's changesets when the
site is built.

Each entry carries a label:

| Label        | What it means for your app                         |
| ------------ | -------------------------------------------------- |
| **Breaking** | You may need to change your code when you upgrade. |
| **Added**    | Something new, and nothing you use changes.        |
| **Fixed**    | A bug fix.                                         |

Older entries name functions as they were then. A later entry may have renamed them.

### minor: nimbus-solana-fee-payer-unfunded (21 October 2026)

A flow the connected wallet pays for refuses a wallet that cannot pay before any work: a new
`NimbusSolanaFlowErrorReason`, `fee-payer-unfunded`, is thrown while `register`, `deposit` (both
transaction versions) and `refundStrandedDeposit` are prepared, before any proving key is
downloaded, any proof made or the committee and data endorser asked. It is raised when the wallet
has no account or holds fewer lamports than the transaction takes from it plus the rent-exempt
minimum it keeps; its `detail` carries `requiredLamports` and `heldLamports` as decimal strings.
The wallet is read with the accounts each flow reads already.

`prepareRegistration` and `prepareDepositRefund` take the priority fee in their options, and
`RegisterDeps` gains `fetchSolanaAccounts`. Relayed withdrawals and transfers are unchanged: the
relayer pays for them.

### patch: nimbus-solana-relay-refused (21 October 2026)

A withdrawal, transfer or merge the relayer refuses (`relay-refused`) gives its notes back at once.
The relayer's definitive refusal, and a committee that withheld its signatures so nothing was
posted, are reported to the note store as `relay-refused`, which ends the attempt, so the abandon
that follows frees the notes and restores the balance instead of holding them until the proof
window closes. A lost answer, or a withheld outcome whose answers do sum, still holds them.

### patch: nimbus-solana-web-coordinator-batches (21 October 2026)

The reads and committee requests a flow makes together through the process coordinator now share
one `prepare` and one `attest`, as the earlier SDK's did, instead of one call per item: a deposit
makes 3 coordinator calls where it made 11, and a relayed spend 3 where it made 7. Busy items are
still re-sent alone, an item's refusal reaches only its caller, and two flows never share a batch.

### patch: nimbus-solana-web-coordinator-busy-items (21 October 2026)

On the coordinator route, a read or committee request an upstream answered busy (a status the
service clients retry, or no answer at all) is sent again on its own, up to three sends in all,
pausing 500 ms and then 1000 ms through the platform's `waitFor`. One 429 or 503 from a guardian,
the screener, the data endorser, the fee enclave, the context API or the relayer no longer fails a
deposit or spend before anything is sent; an item still busy after the third send fails as before.

### patch: nimbus-solana-web-direct-relay-policy (21 October 2026)

On the coordinator route the relayer's policy is read from the relayer itself, as the earlier SDK
read it, so a relayed spend makes one coordinator prepare again instead of two.

### patch: nimbus-solana-web-mainnet-lookup-table (21 October 2026)

The mainnet preset names DE3Y2HM8CrwQfb7nTpuuMFeYeXboBnKUDDrMS4RmJLgY as the deposit lookup table,
the one mainnet-v2 deposits compile against, which holds every address of the table it named
before and 49 more, uUSDv's and kVUSDC's among them.

### patch: nimbus-solana-default-creation-fee (21 October 2026)

A withdrawal to an address whose token account does not exist yet, through a relayer that accepts
a zero fee but does not sponsor creating the account, pays the relayer's published floor and
destination-creation fee in the fee's mint by default, instead of refusing with
`relay-unavailable`. The fee is the prepared stage's `relayerFee` and is settled as every relayer
fee is: out of the amount under `deduct`, on top of it under `add`. Only the default floor
changes: an offered fee below what creating the account costs is still refused, and a relayer
that publishes no payment or creation fee in the mint, or no tip accrual for it, still refuses.
`@umbra/nimbus-solana-web`'s `submitterFee` option documents the same.

### minor: nimbus-web-unregistered-party (21 October 2026)

A deposit or a transfer to a wallet that has not registered throws `NimbusSdkError` with the new
reason `recipient-unregistered`, its message carrying the context API's detail, before the wallet
is asked to sign or anything is sent. It was `service-unavailable`, which an application could
tell from an unreachable service only by its message. When the context API holds no registration
of the session's own identity, or for a withdrawal of the connected wallet, the reason is the new
`account-unregistered`. Both route the same way directly and through the coordinator.

`@umbra/service-client-core`'s `refuseStatus` keeps an RFC 9457 problem body on the `ClientError`
it throws, as `problem`: the answer's HTTP status, the problem's `type`, and its `code` and
`detail` when present. The new `ServiceProblem` type describes it. The reason and message are
unchanged.

### patch: nimbus-solana-web-tsdoc-corrections (21 October 2026)

Correct two TSDoc entries. `unsupported-browser` also names `navigator.storage` and `IDBKeyRange`,
which `loadNimbusSdk` checks for. `ReservedSpend.kind` says what a merge and an escape are. Docs
only: no behaviour changes.

### patch: nimbus-solana-web-misconfigured-arguments (21 October 2026)

A bad argument is refused as `NimbusSdkError` with reason `misconfigured`, before anything is
fetched or read, so `isNimbusSdkError` recognises every caller's mistake:

- `resolvePendingDeposit` refuses a submission whose outcome is not `unknown`. It threw
  `@umbra/nimbus-primitives`' `ProtocolError`, which neither `isNimbusSdkError` nor
  `isNimbusSolanaFlowError` recognised.
- `findMintByIdentifier` refuses an identifier shorter than 32 bytes. It threw a `RangeError`.
- `readHistory` refuses a `limit` that is not a whole number from 1 to 100. It threw `unreadable`,
  and for a session whose store held nothing yet it returned an empty page instead.
- `syncNoteStore` refuses a `pageRows` that is not a whole number from 1 to 1000. It threw the
  note store's `RangeError`, and only for a registered identity; an unregistered one returned
  `unregistered`.

### minor: nimbus-solana-web-reserved-deposits (21 October 2026)

`listReservedSpends` lists a deposit that holds the notes it merges, as `kind: "deposit"`, and
`releaseReservedNotes` and the release that ends every `syncNoteStore` release it as they release a
spend. Before, `readBalances` counted such a deposit's notes as `reserved` while neither listed nor
released them, so a stopped deposit's merged notes stayed held and the application had no call that
freed them. A deposit that merges no notes holds none and is still not listed.

`ReservedSpend.kind` gains the variant `"deposit"`. An application whose `switch` over it is
exhaustive, or which types a table as `Record<ReservedSpend["kind"], …>`, stops compiling until it
handles a deposit.

A deposit released while its transaction may still land keeps its notes until that transaction
lands or can no longer land. `resolvePendingDeposit` still settles it, and a `failed` or `expired`
resolution then answers `intent: "settled"`, the release having stopped it already.

### minor: nimbus-solana-web-transaction-types (21 October 2026)

The package exports the transaction types its public types name, so an application no longer
derives them or imports them from `@umbra/nimbus-solana`:

- `TransactionSubmission`, where a transaction the wallet sent ended up, which a `submitted`
  registration, deposit or refund result carries.
- `TransactionVersion`, the `transactionVersion` the flows' options and `ConnectedWallet` name.
- `ConfirmationCommitment`, the `commitment` the flows' options name.

All three are type-only exports.

### patch: nimbus-solana-web-tsdoc (21 October 2026)

Document every public function and type in full: each field of the configuration, contexts,
options, results and stages, each inline argument, each `NimbusSdkErrorReason` with what an
application does about it, and each function's return values and failures, including the
`misconfigured` refusals of `syncNoteStore`'s `maxRounds` and the `RangeError` its `pageRows`
throws. Comments only; no behaviour changes.

### minor: nimbus-solana-web-app-types (21 October 2026)

The package exports the types an application names, so it no longer imports them from the
packages below it.

- The flows' progress stages: `RegisterStage`, `DepositStage`, `WithdrawStage`, `TransferStage`
  and `RefundStage`.
- `DepositSubmission`, which `resolvePendingDeposit` takes.
- `SpendRefusal` and the refusals a spend result names: `MergeFailureCause`,
  `WalletStoreRefusal`, `LeaseRefusal`, `BeginAttemptRefusal` and `MarkAttemptSentRefusal`.
- `HistoryPosition`, the type of `readHistory`'s `after`.
- The wallet types: `ConnectedWallet`, `WalletConnectionResult`, `WalletDiscoveryOptions` and the
  Wallet Standard's `Wallet`.
- `isNimbusSolanaFlowError`, with `NimbusSolanaFlowError` and `NimbusSolanaFlowErrorReason`, to
  recognise the protocol's own refusals a flow throws.

### minor: nimbus-solana-web-asset-integrity (21 October 2026)

The SDK checks the WebAssembly and scripts it ships before it runs them, and the primitives
before it uses them.

- `build:assets`, which `prepack` runs after `build`, pins every file it writes to `assets/` by
  its SHA-256: in the built `dist/asset-digests.js` for the main thread, and in
  `prover-worker.js` for the files the worker loads. A packed package carries the digests of
  exactly the assets packed with it.
- `loadNimbusSdk` hashes the primitives' module before instantiating it, and the default prover
  worker's script before starting it, refusing a file that is not the pinned one as
  `dependency-nonconforming`, naming the file and both digests. The shipped worker checks each
  `.wasm` on the bytes it instantiates and each glue or helper script before importing it,
  answering `failed` with reason `dependency-nonconforming`. Scripts are imported by URL after
  their check, so a server that answers the check and the import with different bytes is not
  caught; a mismatched build or a corrupted file is.
- `loadNimbusSdk` runs `@umbra/nimbus-primitives/conformance`'s known-answer checks on the loaded
  primitives, refusing a failure as `dependency-nonconforming` naming the primitive and its check.
- `settings.assetPinning` is `pinned` in a packed package, and `unpinned` when it runs from
  source, where no file is checked.
- `NimbusPlatform.computeSha256Digest` is Web Crypto's SHA-256 by default, and
  `platform.startProverWorker` may resolve to its worker.

### minor: nimbus-solana-web-wallets (21 October 2026)

The SDK finds and connects Wallet Standard wallets itself, so an application no longer writes its
own discovery and signer.

- `listWallets(sdk)` lists the installed wallets that can connect, sign messages and sign
  transactions on the SDK's cluster chain (`solana:mainnet` or `solana:devnet`).
- `followWallets(sdk, { onChange })` calls `onChange` with that list whenever a wallet registers or
  unregisters, and returns the function that stops following.
- `openWalletConnection(sdk, { wallet })` asks the wallet to connect and answers `connected` with
  the `WalletStandardSigner` `openNimbusSession` takes and the transaction version the wallet
  signs (`1` when it supports it, else `0`), `no-account` when it offers no account on the
  cluster, or `declined` when the user refuses; a wallet that cannot sign on the cluster, or fails
  to connect, is refused as `wallet-unsupported`.
- Each takes `options.wallets`, the registry to read, which defaults to `@wallet-standard/app`'s
  `getWallets()`.

### major: nimbus-solana-web-shipped-assets (21 October 2026)

The package ships every browser file it runs, so an application copies one folder, serves the page
cross-origin isolated, and loads with `loadNimbusSdk({ cluster: "mainnet" }, { assetsBaseUrl:
"/nimbus/" })`.

- `assets/` holds the primitives' module, the umbra prover's and the witness graph's WASM
  packages, and `prover-worker.js`, a self-contained module worker that loads both WASM modules
  beside itself and answers with `proveWorkerRequest`. `nimbus-solana-web copy-assets <dir>`
  copies it into the directory the application serves.
- `LoadNimbusSdkOptions.assetsBaseUrl` names that directory, ending with `/`. The primitives'
  module is fetched from it unless `endpoints.primitivesWasm` is given, and each proof runs in a
  module worker started from its `prover-worker.js` unless `platform.startProverWorker` is given.
  A value without the trailing slash, or one that is not a URL, is refused as `misconfigured`.
- `loadNimbusSdk` refuses a page that is not cross-origin isolated as `unsupported-browser`,
  naming `Cross-Origin-Opener-Policy: same-origin` and `Cross-Origin-Embedder-Policy:
  require-corp`: the prover's WebAssembly declares shared memory, which a browser creates on no
  other page. `settings.proving.allowSingleThreaded` is `false`, and `threads` the core count.

### major: nimbus-solana-web-mainnet-out-of-the-box (20 October 2026)

Mainnet works out of the box: `loadNimbusSdk({ cluster: "mainnet" }, …)` needs only
`endpoints.primitivesWasm`, which the application serves, and a prover worker.

- The mainnet preset configures every endpoint the production web app reaches: the Solana RPC, the
  context and data APIs on their own hosts, and the relayer, process coordinator, screener node 0,
  data endorser node 0, fee enclave and guardian nodes 1 to 3 behind
  `gateway.api-v2.umbraprivacy.com`. Its proving keys are the mainnet-v2 asset host's `zk/` files,
  pinned by the web app's manifest, with a 2-of-3 statement for registration and the transaction
  circuit and a three-input statement for the absence circuit. `primitivesWasm` stays
  unconfigured on every preset, and the refusal says the application serves it.
- `openNimbusSession` takes a `gatewayToken` option, a bearer token string or an issuer
  `() => Promise<string>` asked once per gateway request. The session holds it as
  `session.gatewayToken` (`NimbusGatewayToken`, a string in a `Secret`), and `session.sdk` is the
  loaded SDK with its `fetch` sending `Authorization: Bearer` to the origins of
  `settings.gatewayEndpoints` and nowhere else. `closeNimbusSession` drops a held token. A string
  that is not an RFC 6750 bearer token is refused as `misconfigured`.
- `NimbusSdkErrorReason` gains `unauthorized`: a gateway service answered 401 or 403, or the
  issuer gave no usable token. The message names the service, never the token. Either status now
  fails at once: a 403 is no longer retried, and a 401 no longer read as the service's refusal.
- `NimbusSettings` gains `gatewayEndpoints` (`NimbusGatewayEndpoint[]`): every configured endpoint
  the preset marks gateway-routed, the coordinator only on the `coordinator` route. Mainnet marks
  all six gateway services, and devnet the guardians and the screener, as each stack's gateway
  routes them.
- Cached circuit artifacts are keyed by the digest the manifest pins, so a key rotated under the
  same constraint system is downloaded afresh, where the cached old key would fail every proof.
  Artifacts cached before this release are downloaded once more.

### major: nimbus-solana-web-merge-notes (20 October 2026)

`withdraw` and `transfer` merge the session's notes first when the largest three cannot cover the
payment, as often as the payment needs, as `@umbra/nimbus-solana`'s one-call flows now do. They
take `mergeTimeout?` (slots for each merge, 300 when omitted), hand `onProgress` the merge stages
(`merge-prepared`, `merge-relayed`, `merge-settled`) before the payment's, and `WithdrawalResult`
and `TransferResult` gain `merge-failed`. A refusal `insufficient` names the total of every note
the session may spend in the pool, zone and mint. The RPC filler gains `fetchFinalizedSlotAfter`,
polling at the preset's interval.

### major: nimbus-solana-web-session-names (20 October 2026)

Renames the public API to sessions and signature secrets. Behaviour, stored bytes and key
derivation are unchanged, and the default `sessionStorage` key prefix stays
`umbra/nimbus-solana-web/account-secret/`, so secrets already stored still open without a signature.

- `openNimbusAccount(sdk, { wallet }, { secretStore?, accountIndex? })` →
  `openNimbusSession(sdk, { connectedWallet }, { signatureSecretStore?, accountIndex? })`
- `OpenNimbusAccountOptions` → `OpenNimbusSessionOptions`
- `OpenNimbusAccountResult` (`{ kind: "opened", account }`) → `OpenNimbusSessionResult`
  (`{ kind: "opened", session }`)
- `closeNimbusAccount(account)` → `closeNimbusSession(session)`
- `NimbusAccount` → `NimbusSession`, whose `session` field (the `WalletSession`) is now
  `walletSession`
- `createSessionStorageAccountSecretStore` → `createTabSignatureSecretStore`
- `createLocalStorageAccountSecretStore` → `createPersistentSignatureSecretStore`
- `createMemoryAccountSecretStore` → `createMemorySignatureSecretStore`
- `AccountSecretStore` (`readAccountSecret`, `writeAccountSecret`, `wipeAccountSecret`) →
  `SignatureSecretStore` (`readSignatureSecret`, `writeSignatureSecret`, `wipeSignatureSecret`)
- `AccountSecretKey` → `SignatureSecretKey`, `AccountSecretReading` → `SignatureSecretReading`,
  `AccountSecretStoreOptions` → `SignatureSecretStoreOptions`
- the stores' `accountSecret` field, in a `found` reading and in `writeSignatureSecret`'s
  arguments → `signatureSecret`
- `ingestAccountActivity(account, …)` → `syncNoteStore(session, …)`
- `AccountActivityResult` → `NoteStoreSyncResult`, `IngestAccountActivityOptions` →
  `SyncNoteStoreOptions`, `AccountActivityRound` → `NoteStoreSyncRound`
- `readAccountBalances(account, …)` → `readBalances(session, …)`, `AccountBalance` → `Balance`
- `readAccountHistory(account, …)` → `readHistory(session, …)`, `AccountHistoryPage` →
  `HistoryPage`, re-exported from `@umbra/nimbus-storage-solana/record-store`
- `refund(ctx, { mint }, options?)` → `refundStrandedDeposit(ctx, { mint }, options?)`,
  `RefundOptions` → `StrandedDepositRefundOptions`, `RefundResult` → `StrandedDepositRefundResult`
- `resolveDeposit(ctx, { submission })` → `resolvePendingDeposit(ctx, { submission })`,
  `DepositResolutionResult` → `PendingDepositResolutionResult`
- the contexts' `account` field → `session`, and `createRegistrationContext`,
  `createDepositContext`, `createWithdrawalContext` and `createTransferContext` take the session

### patch: nimbus-solana-web-mainnet-deployment (20 October 2026)

Mainnet's preset derives keys under the deployment `mainnet`, as the web app does, not the
`mainnet-v2` stack name: under `mainnet-v2` every existing mainnet account would have opened as a
new, empty one. A test pins the web app's own derivation vectors for both clusters.

### major: nimbus-solana-web-flows (20 October 2026)

Adds the contexts (`createRegistrationContext`, `createDepositContext`, `createWithdrawalContext`,
`createTransferContext`), the flows with every dependency filled (`register`, `deposit`, `withdraw`,
`transfer`, `refund`, `resolveDeposit`) and the account reads (`ingestAccountActivity`, which also
takes in each pool's registrations a spend needs, `readAccountBalances`, `readAccountHistory`).
Addresses and mints are base58 `Address`es; a zone travels as `zone: { id, signer }`.

### patch: nimbus-solana-routing-context (20 October 2026)

Every flow's `ctx` is `{ deployment, session, store, routing }`, and `args` holds only the payment.

- `routing` (`FlowRouting`) carries `account`, `poolIndex`, `screenerNodeIndex`,
  `dataEndorserNodeIndex` and `clusterIdentifier`; a registration takes `RegisterRouting`, the
  same without the screener. `clusterIdentifier` leaves the deposit's and spends' `ctx` top level
  and the registration's `args` for it.
- `store` is `{ backend, choices }` (`FlowWalletStore`) everywhere. Withdrawals and transfers no
  longer take an opened `wallet`: they open the store bound to the account's identity, as a
  deposit does, refuse with `store-refused` (`WalletStoreRefusal`) when it will not open, and carry
  the opened store in `PendingSpend<Backend>`, so `relaySpend`, `relayEndorsedSpend` and
  `abandonSpend` no longer read the store from `ctx`.
- `args`: deposit `{ mint, amount, recipient }`, withdraw `{ mint, amount, recipient }` (the
  recipient is the token account and owner `WithdrawDestination` was, now `WithdrawRecipient`),
  transfer `{ mint, amount, recipient }`, register `{}`, refund `{ mint }`, and `resolveDeposit`
  `{ submission }`. `destination` is `recipient` throughout, the deposit stage and the context
  port's `DepositContextRequest` included; `SpendSource` is `SpendPayment`.
- The zone is a flow option: `opts.zone` is `{ kind: "zone-0" }` or
  `{ kind: "zone"; id; signer }`, `id` from 1 to 2^20 - 1 and `signer` a `ZoneSignerPort`, in the
  one-call deposit, withdrawal and transfer and in `prepareDeposit`, `prepareWithdrawal` and
  `prepareTransfer`. `signZoneAuthorisation` leaves `NimbusSolanaDeps`; the defaults spend in
  zone 0.
- A deposit pays a registered identity only: `DepositDestination` and its `program` kind are
  gone, and a recipient the context service resolves with no registration path is refused as
  `context-mismatched`. The wallet's balances and history show the notes the identity owns.

### major: nimbus-solana-web-unregistered-store (19 October 2026)

`openNimbusAccount` no longer gives an unregistered identity's note store a birthday, which made the
store refuse the one `register` sets, and keeps the birthday a registered identity's store already
has. `NimbusAccount.noteStore` is removed; the store is opened where it is read.

### major: nimbus-solana-web-load-and-accounts (19 October 2026)

Replaces `loadNimbusSolanaWeb`, its configuration and platform types, `NimbusSolanaWebError`,
`openNimbusSolanaWebBackend`, `KIT_SOLANA_FORMATS` and the `./coordinated` entry with
`loadNimbusSdk({ cluster }, options?)`, which reads a bundled per-cluster preset completed by its
options (`route: "coordinator"` replaces `./coordinated`), `openNimbusAccount` and
`closeNimbusAccount`, three account secret stores (session storage by default, local storage and
memory), and `NimbusSdkError` with `isNimbusSdkError`. The wallet is no longer part of loading.

### minor: no-sdk-reaches-for-global-fetch (19 October 2026)

No SDK package reaches for the global `fetch`.

`@umbra/circuit-artifacts`: `FetchDeps.fetch` is required, and `fetchManifest`, the encodings'
`download` and the resolver no longer fall back to the global. `deps` stays after `opts` and is
required: `fetchManifest(args, opts, { fetch })`, `download(source, args, opts, { fetch })`.
`ResolveDeps` extends `FetchDeps`, and the resolver hands `download` that `fetch`, so an encoding
module still passes as `EncodingDeps` whole: `{ ...plain, fetch, ...store }`.

`@umbra/nimbus-robinhood`: `readArtifactManifest` takes required deps with `fetch`, and
`createArtifactResolver`'s deps carry the `fetch` its downloads go through.

`@umbra/nimbus-solana-web`: Kit's Solana RPC runs on a transport over the platform's `fetch`
(Kit's own HTTP transport calls the global), so every RPC request, like every service request,
goes through the platform's `fetch`. The transport keeps Kit's bigint-preserving JSON and its HTTP
error; it does not coalesce identical requests in flight together, as Kit's default does.

`@umbra/solana-indexer-client`: the injected `fetch` is called with no receiver, so a browser's own
`fetch` can be passed as `{ fetch }`.

### patch: inject-fetch-service-clients (19 October 2026)

Every service client takes `fetch` as an injected dependency, with no default: nothing reaches
for the global `fetch`. `@umbra/service-client-core` exports `ServiceDeps` (`{ fetch }`), and its
`request`, `requestJson`, `requestBytes` and `isLive` take `deps` before their optional `opts`:
`(ctx, args, deps, opts?)`. A call that was `requestJson(ctx, args, opts)` becomes
`requestJson(ctx, args, { fetch }, opts)`. The injected `fetch` is called with no receiver, so a
browser's own `fetch` can be passed as `{ fetch }`.

In each client, every function that reaches its service takes the same deps, in the same position:

- A function whose deps slot was empty now takes `deps: Pick<ServiceDeps, "fetch">` before its
  opts, and an optional `_args` becomes a required `{}`. For example,
  `readIdentity(ctx, {}, { fetch })`.
- `GuardianDeps` and `FeeEnclaveDeps` gain `fetch`, so the endorse calls, the committee helpers and
  `provideFeeClaim` keep their positions and take it with their seal primitives. The functions
  that only seal (`buildProcessEndorsement`, `sealFeeClaim`) take the primitives and the random
  source without it.
- Factory-made clients (`createRelayClient`, `createDepositDataClient`, `createSpendDataClient`)
  take it in their closures' existing deps slot, which was typed `unknown` and ignored. The
  directories whose closure takes one args object (`createRegistrationDirectory`,
  `createOwnerDirectory`) take it as the closure's second parameter.
- note-sync's `DownloadDeps` gains `fetch`, and its readers (`fetchManifest`, `fetchChunk`,
  `fetchChunkHeader`, `fetchChunkRange`, the page and record reads) take it before their opts.

`nimbus-robinhood`'s `FlowDeps` gains `fetch`, and `createFlowDeps` takes it beside the signer, the
prover and the storage; `createRpc`, `createAuthorisers`, `createCoordinatedAuthorisers`, the
JSON-RPC, indexer and relayer readers take it in their deps. `nimbus-solana-web` passes the
platform's `fetch` to every client, direct or through the coordinator, and `robinhood-pool-cli`
passes the platform's own at each call, as an entry point does.

### minor: nimbus-solana-web-zone-signer (19 October 2026)

The deps fill `nimbus-solana`'s new `signZoneAuthorisation` with a signer that refuses every zone,
naming it and the side: no zone signer service exists, zone 0 never asks one, and a caller using
another zone replaces the member.

### patch: nimbus-solana-web-context-leaf (19 October 2026)

The context filler takes a registered standing's leaf from `@umbra/solana-context-client`'s `leaf`,
which is `unassigned` exactly when the context API serves no index, instead of inferring it from
`provable`. Deposit and spend contexts the API serves now fill the port: the client parses each
path's leaf index and shape and each gap's value and shape, which the filler refused as unreadable
while the client cast them.

### patch: nimbus-solana-web-wallet-entry (19 October 2026)

Imports the wallet's types from `@umbra/nimbus-solana/wallet`, the entry `./wallet-store` became.

### minor: nimbus-solana-web (19 October 2026)

Add the browser SDK: `loadNimbusSolanaWeb(config, platform)` loads the primitives' WASM module and
returns the decoded deployment and one deps object that fills every member `@umbra/nimbus-solana`'s
flows and wallet call. Crypto comes from `@umbra/nimbus-primitives-wasm`; Anza's formats and the
instruction builders from `@solana/kit` and `@solana-program/*` (`KIT_SOLANA_FORMATS`); the RPC
port, the platform wallet binding and the sync's pool reading from Kit's RPC; the wallet signer from
the Wallet Standard's `solana:signMessage` and `solana:signTransaction`; the lock from Web Locks;
storage from the IndexedDB backend `openNimbusSolanaWebBackend` opens under
`buildNoteStoreBackendName`; the indexer feeds from `@umbra/solana-indexer-client`; every service
from its client; proving keys from `@umbra/circuit-artifacts`, cached through `@umbra/store-web` and
checked against the one verifying key the selection names: the configured statement, the manifest's
verifying key, and its body in the deployed program's ELF; and proofs from
`@umbra/prover`'s umbra backend in a worker that runs `./prover-worker`'s `proveWorkerRequest`.
`./coordinated`'s `loadCoordinatedNimbusSolanaWeb` reaches a transaction's reads, committee and relay
through the process coordinator. Configuration is data; nothing is bundled.


Last updated 21 October 2026
