@miden-sdk/miden-sdk 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,6 +29,7 @@ import type {
29
29
  AuthSecretKey,
30
30
  AccountStorageRequirements,
31
31
  TransactionScript,
32
+ NoteScript,
32
33
  AdviceInputs,
33
34
  FeltArray,
34
35
  } from "./crates/miden_client_web";
@@ -36,6 +37,13 @@ import type {
36
37
  // Import the full namespace for the MidenArrayConstructors type
37
38
  import type * as WasmExports from "./crates/miden_client_web";
38
39
 
40
+ // Source of truth for standalone-wrapper return types. By deriving them from
41
+ // the wasm-bindgen-generated namespace (rather than hand-writing `: Note`),
42
+ // the declarations below cannot drift from the actual runtime behavior — the
43
+ // exact class of bug behind #2042. Any forwarder-style wrapper should follow
44
+ // the same pattern: `ReturnType<WasmModule["Class"]["method"]>`.
45
+ type WasmModule = typeof import("./crates/miden_client_web");
46
+
39
47
  // ════════════════════════════════════════════════════════════════
40
48
  // Callback types for external keystore support
41
49
  // ════════════════════════════════════════════════════════════════
@@ -105,6 +113,18 @@ export declare const StorageMode: {
105
113
  /** Union of valid StorageMode string values. */
106
114
  export type StorageMode = "public" | "private" | "network";
107
115
 
116
+ /**
117
+ * Library linking mode for script compilation.
118
+ * Use `Linking.Dynamic` or `Linking.Static` instead of raw strings.
119
+ */
120
+ export declare const Linking: {
121
+ readonly Dynamic: "dynamic";
122
+ readonly Static: "static";
123
+ };
124
+
125
+ /** Union of valid Linking string values. */
126
+ export type Linking = "dynamic" | "static";
127
+
108
128
  /**
109
129
  * Union of all values in the AccountType const.
110
130
  */
@@ -770,10 +790,10 @@ export interface CompileTxScriptLibrary {
770
790
  /** MASM source code for the library. */
771
791
  code: string;
772
792
  /**
773
- * `"dynamic"` (default) — procedures are linked via DYNCALL at runtime.
774
- * `"static"` — procedures are inlined at compile time.
793
+ * `Linking.Dynamic` (default) — procedures are linked via DYNCALL at runtime.
794
+ * `Linking.Static` — procedures are inlined at compile time.
775
795
  */
776
- linking?: "dynamic" | "static";
796
+ linking?: Linking;
777
797
  }
778
798
 
779
799
  export interface CompileTxScriptOptions {
@@ -783,7 +803,33 @@ export interface CompileTxScriptOptions {
783
803
  libraries?: CompileTxScriptLibrary[];
784
804
  }
785
805
 
786
- export interface CompilerResource {
806
+ export interface CompileNoteScriptOptions {
807
+ /** MASM source code for the note script. */
808
+ code: string;
809
+ /** Component libraries to link. */
810
+ libraries?: CompileTxScriptLibrary[];
811
+ }
812
+
813
+ export declare class CompilerResource {
814
+ /**
815
+ * Create a standalone `CompilerResource` over a WASM `WebClient` proxy.
816
+ *
817
+ * Normally accessed as `client.compile` on a `MidenClient`; construct
818
+ * directly only when you need the compiler surface without the full
819
+ * `MidenClient` wrapper (e.g. inside a framework-specific hook).
820
+ *
821
+ * @param inner - The WASM `WebClient` (e.g. the `WasmWebClient` proxy).
822
+ * @param getWasm - Async accessor for the WASM module, used to reach
823
+ * `AccountComponent.compile` at runtime. `getWasmOrThrow` satisfies this.
824
+ * @param client - Optional wrapper with `assertNotTerminated()`; used
825
+ * internally by `MidenClient` and may be omitted by external callers.
826
+ */
827
+ constructor(
828
+ inner: WasmExports.WebClient,
829
+ getWasm: () => Promise<typeof WasmExports>,
830
+ client?: { assertNotTerminated(): void } | null
831
+ );
832
+
787
833
  /**
788
834
  * Compile MASM source into an AccountComponent.
789
835
  *
@@ -796,6 +842,12 @@ export interface CompilerResource {
796
842
  * @param options - Script source code and optional libraries to link.
797
843
  */
798
844
  txScript(options: CompileTxScriptOptions): Promise<TransactionScript>;
845
+ /**
846
+ * Compile MASM source into a NoteScript.
847
+ *
848
+ * @param options - Script source code and optional libraries to link.
849
+ */
850
+ noteScript(options: CompileNoteScriptOptions): Promise<NoteScript>;
799
851
  }
800
852
 
801
853
  export interface TagsResource {
@@ -908,13 +960,19 @@ export declare class MidenClient {
908
960
  // ════════════════════════════════════════════════════════════════
909
961
 
910
962
  /** Creates a P2ID (Pay-to-ID) note. */
911
- export declare function createP2IDNote(options: NoteOptions): OutputNote;
963
+ export declare function createP2IDNote(
964
+ options: NoteOptions
965
+ ): ReturnType<WasmModule["Note"]["createP2IDNote"]>;
912
966
 
913
967
  /** Creates a P2IDE (Pay-to-ID with Expiration) note. */
914
- export declare function createP2IDENote(options: P2IDEOptions): OutputNote;
968
+ export declare function createP2IDENote(
969
+ options: P2IDEOptions
970
+ ): ReturnType<WasmModule["Note"]["createP2IDENote"]>;
915
971
 
916
972
  /** Builds a swap tag for note matching. Returns a NoteTag (use `.asU32()` for the numeric value). */
917
- export declare function buildSwapTag(options: BuildSwapTagOptions): NoteTag;
973
+ export declare function buildSwapTag(
974
+ options: BuildSwapTagOptions
975
+ ): ReturnType<WasmModule["WebClient"]["buildSwapTag"]>;
918
976
 
919
977
  /** Exports the entire contents of an IndexedDB store as a JSON string. */
920
978
  export declare function exportStore(storeName: string): Promise<string>;
Binary file
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import loadWasm from './wasm.js';
2
- export { Account, AccountArray, AccountBuilder, AccountBuilderResult, AccountCode, AccountComponent, AccountComponentCode, AccountDelta, AccountFile, AccountHeader, AccountId, AccountIdArray, AccountInterface, AccountProof, AccountReader, AccountStatus, AccountStorage, AccountStorageDelta, AccountStorageMode, AccountStorageRequirements, AccountVaultDelta, Address, AdviceInputs, AdviceMap, AssetVault, AuthFalcon512RpoMultisigConfig, AuthSecretKey, BasicFungibleFaucetComponent, BlockHeader, CodeBuilder, CommittedNote, ConsumableNoteRecord, Endpoint, ExecutedTransaction, Felt, FeltArray, FetchedAccount, FetchedNote, FlattenedU8Vec, ForeignAccount, ForeignAccountArray, FungibleAsset, FungibleAssetDelta, FungibleAssetDeltaItem, GetProceduresResultItem, InputNote, InputNoteRecord, InputNoteState, InputNotes, IntoUnderlyingByteSource, IntoUnderlyingSink, IntoUnderlyingSource, JsAccountUpdate, JsStateSyncUpdate, JsStorageMapEntry, JsStorageSlot, JsVaultAsset, Library, MerklePath, NetworkId, NetworkType, Note, NoteAndArgs, NoteAndArgsArray, NoteArray, NoteAssets, NoteAttachment, NoteAttachmentKind, NoteAttachmentScheme, NoteConsumability, NoteConsumptionStatus, NoteDetails, NoteDetailsAndTag, NoteDetailsAndTagArray, NoteExecutionHint, NoteExportFormat, NoteFile, NoteFilter, NoteFilterTypes, NoteHeader, NoteId, NoteIdAndArgs, NoteIdAndArgsArray, NoteInclusionProof, NoteLocation, NoteMetadata, NoteRecipient, NoteRecipientArray, NoteScript, NoteStorage, NoteSyncBlock, NoteSyncInfo, NoteTag, NoteType, OutputNote, OutputNoteArray, OutputNoteRecord, OutputNoteState, OutputNotes, Package, PartialNote, Poseidon2, ProcedureThreshold, Program, ProvenTransaction, PublicKey, RpcClient, Rpo256, SerializedInputNoteData, SerializedOutputNoteData, SerializedTransactionData, Signature, SigningInputs, SigningInputsType, SlotAndKeys, SparseMerklePath, StorageMap, StorageMapEntry, StorageMapInfo, StorageMapUpdate, StorageSlot, StorageSlotArray, SyncSummary, TestUtils, TokenSymbol, TransactionArgs, TransactionFilter, TransactionId, TransactionProver, TransactionRecord, TransactionRequest, TransactionRequestBuilder, TransactionResult, TransactionScript, TransactionScriptInputPair, TransactionScriptInputPairArray, TransactionStatus, TransactionStoreUpdate, TransactionSummary, WebClient, WebKeystoreApi, Word, createAuthFalcon512RpoMultisig, exportStore, importStore, initSync, setupLogging } from './Cargo-BZOulF0S.js';
2
+ export { Account, AccountArray, AccountBuilder, AccountBuilderResult, AccountCode, AccountComponent, AccountComponentCode, AccountDelta, AccountFile, AccountHeader, AccountId, AccountIdArray, AccountInterface, AccountProof, AccountReader, AccountStatus, AccountStorage, AccountStorageDelta, AccountStorageMode, AccountStorageRequirements, AccountVaultDelta, Address, AdviceInputs, AdviceMap, AssetVault, AuthFalcon512RpoMultisigConfig, AuthSecretKey, BasicFungibleFaucetComponent, BlockHeader, CodeBuilder, CommittedNote, ConsumableNoteRecord, Endpoint, ExecutedTransaction, Felt, FeltArray, FetchedAccount, FetchedNote, FlattenedU8Vec, ForeignAccount, ForeignAccountArray, FungibleAsset, FungibleAssetDelta, FungibleAssetDeltaItem, GetProceduresResultItem, InputNote, InputNoteRecord, InputNoteState, InputNotes, IntoUnderlyingByteSource, IntoUnderlyingSink, IntoUnderlyingSource, JsAccountUpdate, JsStateSyncUpdate, JsStorageMapEntry, JsStorageSlot, JsVaultAsset, Library, MerklePath, NetworkId, NetworkType, Note, NoteAndArgs, NoteAndArgsArray, NoteArray, NoteAssets, NoteAttachment, NoteAttachmentKind, NoteAttachmentScheme, NoteConsumability, NoteConsumptionStatus, NoteDetails, NoteDetailsAndTag, NoteDetailsAndTagArray, NoteExecutionHint, NoteExportFormat, NoteFile, NoteFilter, NoteFilterTypes, NoteHeader, NoteId, NoteIdAndArgs, NoteIdAndArgsArray, NoteInclusionProof, NoteLocation, NoteMetadata, NoteRecipient, NoteRecipientArray, NoteScript, NoteStorage, NoteSyncBlock, NoteSyncInfo, NoteTag, NoteType, OutputNote, OutputNoteArray, OutputNoteRecord, OutputNoteState, OutputNotes, Package, PartialNote, Poseidon2, ProcedureThreshold, Program, ProvenTransaction, PublicKey, RpcClient, Rpo256, SerializedInputNoteData, SerializedOutputNoteData, SerializedTransactionData, Signature, SigningInputs, SigningInputsType, SlotAndKeys, SparseMerklePath, StorageMap, StorageMapEntry, StorageMapInfo, StorageMapUpdate, StorageSlot, StorageSlotArray, SyncSummary, TestUtils, TokenSymbol, TransactionArgs, TransactionFilter, TransactionId, TransactionProver, TransactionRecord, TransactionRequest, TransactionRequestBuilder, TransactionResult, TransactionScript, TransactionScriptInputPair, TransactionScriptInputPairArray, TransactionStatus, TransactionStoreUpdate, TransactionSummary, WebClient, WebKeystoreApi, Word, createAuthFalcon512RpoMultisig, exportStore, importStore, initSync, setupLogging } from './Cargo-D44KIErf.js';
3
3
 
4
4
  const WorkerAction = Object.freeze({
5
5
  INIT: "init",
@@ -1387,7 +1387,7 @@ class CompilerResource {
1387
1387
  #getWasm;
1388
1388
  #client;
1389
1389
 
1390
- constructor(inner, getWasm, client) {
1390
+ constructor(inner, getWasm, client = null) {
1391
1391
  this.#inner = inner;
1392
1392
  this.#getWasm = getWasm;
1393
1393
  this.#client = client;
@@ -1400,7 +1400,7 @@ class CompilerResource {
1400
1400
  * @returns {Promise<AccountComponent>}
1401
1401
  */
1402
1402
  async component({ code, slots = [], supportAllTypes = true }) {
1403
- this.#client.assertNotTerminated();
1403
+ this.#client?.assertNotTerminated();
1404
1404
  const wasm = await this.#getWasm();
1405
1405
  const builder = this.#inner.createCodeBuilder();
1406
1406
  const compiled = builder.compileAccountComponentCode(code);
@@ -1415,26 +1415,45 @@ class CompilerResource {
1415
1415
  * @returns {Promise<TransactionScript>}
1416
1416
  */
1417
1417
  async txScript({ code, libraries = [] }) {
1418
- this.#client.assertNotTerminated();
1418
+ this.#client?.assertNotTerminated();
1419
1419
  // Ensure WASM is initialized (result unused — only #inner needs it)
1420
1420
  await this.#getWasm();
1421
1421
  const builder = this.#inner.createCodeBuilder();
1422
- for (const lib of libraries) {
1423
- if (lib && typeof lib.namespace === "string") {
1424
- // Inline { namespace, code, linking? } — build and link automatically
1425
- const built = builder.buildLibrary(lib.namespace, lib.code);
1426
- if (lib.linking === "static") {
1427
- builder.linkStaticLibrary(built);
1428
- } else {
1429
- // Default: "dynamic" matches existing tutorial behavior
1430
- builder.linkDynamicLibrary(built);
1431
- }
1422
+ linkLibraries(builder, libraries);
1423
+ return builder.compileTxScript(code);
1424
+ }
1425
+
1426
+ /**
1427
+ * Compiles a note script, optionally linking named libraries inline.
1428
+ *
1429
+ * @param {{ code: string, libraries?: Array<{ namespace: string, code: string, linking?: "dynamic" | "static" }> }} opts
1430
+ * @returns {Promise<NoteScript>}
1431
+ */
1432
+ async noteScript({ code, libraries = [] }) {
1433
+ this.#client?.assertNotTerminated();
1434
+ await this.#getWasm();
1435
+ const builder = this.#inner.createCodeBuilder();
1436
+ linkLibraries(builder, libraries);
1437
+ return builder.compileNoteScript(code);
1438
+ }
1439
+ }
1440
+
1441
+ // Builds and links each library entry against `builder`. Inline
1442
+ // `{ namespace, code, linking? }` entries are built via `buildLibrary` and
1443
+ // linked according to `linking` (defaulting to dynamic, matching tutorial
1444
+ // behavior). Pre-built library objects are linked dynamically.
1445
+ function linkLibraries(builder, libraries) {
1446
+ for (const lib of libraries) {
1447
+ if (lib && typeof lib.namespace === "string") {
1448
+ const built = builder.buildLibrary(lib.namespace, lib.code);
1449
+ if (lib.linking === "static") {
1450
+ builder.linkStaticLibrary(built);
1432
1451
  } else {
1433
- // Pre-built library object — link dynamically
1434
- builder.linkDynamicLibrary(lib);
1452
+ builder.linkDynamicLibrary(built);
1435
1453
  }
1454
+ } else {
1455
+ builder.linkDynamicLibrary(lib);
1436
1456
  }
1437
- return builder.compileTxScript(code);
1438
1457
  }
1439
1458
  }
1440
1459
 
@@ -1932,6 +1951,11 @@ const StorageMode = Object.freeze({
1932
1951
  Network: "network",
1933
1952
  });
1934
1953
 
1954
+ const Linking = Object.freeze({
1955
+ Dynamic: "dynamic",
1956
+ Static: "static",
1957
+ });
1958
+
1935
1959
  const MOCK_STORE_NAME = "mock_client_db";
1936
1960
 
1937
1961
  const buildTypedArraysExport = (exportObject) => {
@@ -2052,6 +2076,46 @@ function createClientProxy(instance) {
2052
2076
  }
2053
2077
 
2054
2078
  class WebClient {
2079
+ /**
2080
+ * Controls which worker variant is spawned when a WebClient is constructed.
2081
+ *
2082
+ * - `"auto"` (default): pick `classic` on Safari/WKWebView (where module
2083
+ * workers have a very slow cold start), `module` everywhere else.
2084
+ * - `"module"`: always use the `.mjs` ES-module worker. Required for webpack
2085
+ * 5 / Next.js consumers so the asset tracer can see the WASM URL.
2086
+ * - `"classic"`: always use the `.js` classic-script worker. Required on
2087
+ * Safari/WKWebView. Set this if your consumer bundler (or your host app)
2088
+ * does not support module workers.
2089
+ *
2090
+ * Set before the first `WebClient.createClient(...)` call.
2091
+ */
2092
+ static workerMode = "auto";
2093
+
2094
+ /**
2095
+ * Decide between the module and classic worker variants based on
2096
+ * `WebClient.workerMode` and (when `auto`) the current user agent.
2097
+ * @returns {boolean} true when the classic script should be used.
2098
+ * @private
2099
+ */
2100
+ static _shouldUseClassicWorker() {
2101
+ const mode = WebClient.workerMode;
2102
+ if (mode === "module") return false;
2103
+ if (mode === "classic") return true;
2104
+ // auto: classic on Safari/WKWebView, module everywhere else.
2105
+ const ua =
2106
+ typeof navigator !== "undefined" && navigator.userAgent
2107
+ ? navigator.userAgent
2108
+ : "";
2109
+ // Chromium-based browsers (Chrome, Edge, Brave, Opera, Chromium-based
2110
+ // Android WebView) handle module workers fine.
2111
+ if (/Chrome\/|Chromium\//.test(ua)) return false;
2112
+ // Safari (desktop + iOS) and WKWebView-without-Chrome (e.g. Capacitor host)
2113
+ // both have AppleWebKit but no Chrome/Chromium in the UA. Prefer classic.
2114
+ if (/AppleWebKit/.test(ua)) return true;
2115
+ // Firefox, jsdom, node without navigator, etc. — module worker is fine.
2116
+ return false;
2117
+ }
2118
+
2055
2119
  /**
2056
2120
  * Create a WebClient wrapper.
2057
2121
  *
@@ -2098,13 +2162,36 @@ class WebClient {
2098
2162
  // Check if Web Workers are available.
2099
2163
  if (typeof Worker !== "undefined") {
2100
2164
  console.log("WebClient: Web Workers are available.");
2101
- // Create the worker.
2102
- // Classic worker (not module) the worker is built as a self-contained
2103
- // async-IIFE by the rollup config, compatible with all browsers including
2104
- // Safari/WKWebView which is extremely slow with module workers.
2105
- this.worker = new Worker(
2106
- new URL("./workers/web-client-methods-worker.js", import.meta.url)
2107
- );
2165
+ // Pick between the module and classic worker variants at runtime — see
2166
+ // `WebClient.workerMode` below. Both branches keep the
2167
+ // `new Worker(new URL("...", import.meta.url), ...)` form fully literal:
2168
+ // webpack 5's new-worker detector is PURELY SYNTACTIC and only triggers
2169
+ // a proper worker sub-compilation (with asset+chunk tracing into the
2170
+ // Cargo glue and the sibling WASM) when it sees that exact pattern
2171
+ // spelled inline. Hoisting either URL into a variable downgrades the
2172
+ // detection to a plain "copy file as asset" — which in turn makes the
2173
+ // worker's `await import("./Cargo-*.js")` 404 because webpack never
2174
+ // emitted a chunk for it. The bit of duplication here is load-bearing.
2175
+ //
2176
+ // - module (`.module.js` with `{ type: "module" }`): `import.meta.url`
2177
+ // inside the Cargo glue is preserved so webpack/Vite can resolve the
2178
+ // WASM URL statically. Preferred everywhere EXCEPT Safari/WKWebView.
2179
+ // - classic (`.js`, no options): self-contained async IIFE with
2180
+ // `import.meta.url` rewritten to `self.location.href`; the only form
2181
+ // Safari/WKWebView can cold-start in a reasonable time.
2182
+ if (WebClient._shouldUseClassicWorker()) {
2183
+ this.worker = new Worker(
2184
+ new URL("./workers/web-client-methods-worker.js", import.meta.url)
2185
+ );
2186
+ } else {
2187
+ this.worker = new Worker(
2188
+ new URL(
2189
+ "./workers/web-client-methods-worker.module.js",
2190
+ import.meta.url
2191
+ ),
2192
+ { type: "module" }
2193
+ );
2194
+ }
2108
2195
 
2109
2196
  // Map to track pending worker requests.
2110
2197
  this.pendingRequests = new Map();
@@ -2901,5 +2988,5 @@ MidenClient._MockWasmWebClient = MockWebClient;
2901
2988
  MidenClient._getWasmOrThrow = getWasmOrThrow;
2902
2989
  _setWebClient(WebClient);
2903
2990
 
2904
- export { AccountType, AuthScheme, MidenArrays, MidenClient, MockWebClient as MockWasmWebClient, NoteVisibility, StorageMode, WebClient as WasmWebClient, buildSwapTag, createP2IDENote, createP2IDNote, getWasmOrThrow };
2991
+ export { AccountType, AuthScheme, CompilerResource, Linking, MidenArrays, MidenClient, MockWebClient as MockWasmWebClient, NoteVisibility, StorageMode, WebClient as WasmWebClient, buildSwapTag, createP2IDENote, createP2IDNote, getWasmOrThrow };
2905
2992
  //# sourceMappingURL=index.js.map