Skip to content

v0.17.4

Choose a tag to compare

@WiktorStarczewski WiktorStarczewski released this 18 Oct 09:15
1417eec

Enhancements

  • [FEATURE][web] Add the multisig auth args to a request that another party built with client.withFeeAwareAuth(request, account, options?). It returns a copy of the request with the same auth argument and advice-map preimage that feeAwareTransactionRequestBuilder declares, and keeps every other field; for any other account it returns the request unchanged, auth argument and all. It takes the same options, uses the salt that the request declares when feeConversionSalt is omitted, and for a multisig refuses a request that already has an auth argument (AUTH_ALREADY_SET). The copy executes at the tip without declaring its bound block, so a co-signer cannot read that block from blockNumbers() and syncs before previewing it. A wallet can now execute a dApp's request that declares no salt from a multisig account without rebuilding it (#477, rust-sdk#2708).
  • [FEATURE][web] Set auth args on a finished request with request.withAuthArgs(preimage: Felt[]), which mirrors miden-client's TransactionRequest::with_auth_args. It returns a copy whose auth argument is the Poseidon2 hash of preimage, with preimage in the advice map, and replaces an existing auth argument and a declared fee conversion salt. In the browser build it consumes the Felts it is given, so pass fresh ones to another call (#477).

Fixes

  • [FIX][web] The Node.js SDK now runs on Alpine and other musl Linux distributions. Releases publish a new @miden-sdk/node-linux-x64-musl native package alongside @miden-sdk/node-linux-x64-gnu, and the loader picks between the two by the runtime C library, so a musl-based container (a common ECS or Docker base image) no longer fails at import with Miden napi module not found. Both Linux packages declare a libc field, so npm and pnpm install only the matching one. With npm, an install for Linux from another OS (npm install --os=linux --cpu=x64, as when bundling on macOS) must now also pass --libc=glibc, or --libc=musl for an Alpine target, or npm skips both Linux packages (#234).
  • [FIX][web] When the Node.js native addon cannot be loaded, the error now names the platform, CPU and Node version, every package it tried, the real failure of each resolution step and the fixes for the common causes, instead of a generic "build it with cargo" message. A MIDEN_MODULE_PATH that fails to load now throws an error naming that path and the load failure (#234).
  • [FIX][web] InputNotes.getNote() and OutputNotes.getNote() now throw a catchable out-of-bounds error naming the index and the length instead of aborting the WASM module, and InputNotes.numNotes() and getNote() handle the 1024 input notes a transaction allows instead of aborting above 255 notes or reading a different note for an index of 256 or more (#306).
  • [FIX][web] accounts.create now rejects a contract none of whose components exports a non-auth (@account_procedure) procedure, as its error already stated, instead of creating an account nothing can call into; every transaction calling into it failed in the kernel with push_procedure_index. compile.component also logs a [miden-sdk] console warning when the compiled component has no procedures, and still returns it, since a storage-only component is legitimate beside one that has procedures (#402).
  • [FIX][react] formatAssetAmount puts a single leading minus on a negative amount (-525n at 2 decimals is "-5.25", was "-5.-25"), and parseAssetAmount throws for a negative or malformed amount instead of returning a wrong value ("--1" gave 1n, "-5.25" at 2 decimals gave -475n) (#275).
  • [FIX][react] MidenProvider rendered without a config prop no longer rebuilds its WebClient on every store update (#269).
  • [FIX][web] getInputNotes() and getOutputNotes() now reject with a catchable error instead of aborting the WASM module when a NoteFilter lacks the note ids or script roots its type needs, or a Unique filter holds other than one note id (#268).
  • [FIX][react] useNotes and useNoteStream with a different status, or useNotes with a different accountId, no longer show each other's notes, and a mounted useNotes fetches again when the provider switches signer identity (#280, #284).
  • [FIX][web] Every call that writes the chain MMR, not only the syncs, now holds the per-store Web Lock, so two clients on one browser store, in two tabs or one replacing another that is still finishing a call, can no longer interleave their writes to it. Interleaved, a note import and a sync could store a tracked block header with an MMR path too short for the chain, after which every sync and import failed with inconsistent partial mmr: missing sibling for tracked leaf at position N. A store already in that state is not repaired. The frontend-pitfalls skill shipped with the package (FP2) lists the calls that take the lock. Account creation requests and waits for it only on a store still at genesis, for the sync it runs first there, and releases it before it generates a key, stores the account or calls an external keystore's insertKey, so no application callback runs under the lock. The new WasmWebClient.syncBeforeAccountCreation() runs that sync on its own, under the same rule. The lock is per store opened: a client that omits storeName and one naming the store it defaults to, MidenClientDB_<network id>, take one lock, and clients on different default stores do not block each other. The new top-level resolveStoreName(nodeUrl, storeName) returns the name of the store a client created with those arguments opens. Three changes in behaviour. A call waiting for another client's lock holds its own client's queue, so later calls on that client wait behind it, and its observation's durationMs, timed from its turn on that queue, includes the wait: a slow syncState, syncChain, syncNoteTransport, importNoteFile (notes.import), fetchPrivateNotes (notes.fetchPrivate), or, on a store still at genesis, syncBeforeAccountCreation or account creation can be lock wait. A call of a sync shares a pending run of it only on the same client, and only while no other call has been queued on that client since the run, so it never settles ahead of a call made before it; a shared run reports one observation. The same sync on another client on the store runs its own, serialized by the lock. And a withSyncLock callback, which holds the same lock, could await a non-sync call on a client of that store and now cannot, since that call can queue behind a store-locked call of that client, an auto-sync for example, that waits for the callback's lock. The callback must not wait, directly or through any lock or queue such as @miden-sdk/react's runExclusive, for any call on a client of that store, or every client on the store stops (rust-sdk#2713).

Changes

  • [CHANGE][web] The browser (IndexedDB) store is no longer reset when the SDK's minor or major version changes. It is kept across client upgrades, keys, accounts and notes included, and a schema change migrates the existing data in place. This release clears a store once, and only if it was last written by a client older than 0.17.0 (a 0.17.0 release candidate included); every store a 0.17.0 or later client wrote is kept. A client no longer opens a store written by a newer client (one with a newer store schema): it deletes nothing, and client creation fails with an error saying the store was written by a newer client and to upgrade the SDK, or clear the site's data to start over. importStore follows the same rule: it refuses, leaving the store unchanged, a dump with no client version stamp or one exported by a client older than 0.17.0 or newer than the running one. WebClient.createClient now reports the store's reason for any failed open as Failed to initialize IdxdbStore: <reason> instead of a bare Failed to initialize IdxdbStore (#464).