@miden-sdk/miden-sdk 0.15.0-alpha.6 → 0.15.0

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.
Files changed (43) hide show
  1. package/dist/mt/{Cargo-C9UbiAcT.js → Cargo-1zqmsGGR.js} +314 -96
  2. package/dist/mt/Cargo-1zqmsGGR.js.map +1 -0
  3. package/dist/mt/api-types.d.ts +17 -24
  4. package/dist/mt/assets/miden_client_web.wasm +0 -0
  5. package/dist/mt/crates/miden_client_web.d.ts +42 -19
  6. package/dist/mt/eager.js +1 -1
  7. package/dist/mt/index.js +284 -267
  8. package/dist/mt/index.js.map +1 -1
  9. package/dist/mt/wasm.js +1 -1
  10. package/dist/mt/workerHelpers.js +1 -1
  11. package/dist/mt/workers/{Cargo-C9UbiAcT-Z344cyB1.js → Cargo-1zqmsGGR-COfl7R3D.js} +314 -96
  12. package/dist/mt/workers/Cargo-1zqmsGGR-COfl7R3D.js.map +1 -0
  13. package/dist/mt/workers/assets/miden_client_web.wasm +0 -0
  14. package/dist/mt/workers/web-client-methods-worker.js +315 -96
  15. package/dist/mt/workers/web-client-methods-worker.js.map +1 -1
  16. package/dist/mt/workers/web-client-methods-worker.module.js +1 -1
  17. package/dist/mt/workers/web-client-methods-worker.module.js.map +1 -1
  18. package/dist/mt/workers/workerHelpers.js +1 -1
  19. package/dist/st/{Cargo-OZMlHpic.js → Cargo-qHCIdWdN.js} +315 -98
  20. package/dist/st/Cargo-qHCIdWdN.js.map +1 -0
  21. package/dist/st/api-types.d.ts +17 -24
  22. package/dist/st/assets/miden_client_web.wasm +0 -0
  23. package/dist/st/crates/miden_client_web.d.ts +42 -19
  24. package/dist/st/eager.js +1 -1
  25. package/dist/st/index.js +284 -267
  26. package/dist/st/index.js.map +1 -1
  27. package/dist/st/wasm.js +1 -1
  28. package/dist/st/workers/{Cargo-OZMlHpic-DZjvJlWc.js → Cargo-qHCIdWdN-CZmgHdJc.js} +315 -98
  29. package/dist/st/workers/Cargo-qHCIdWdN-CZmgHdJc.js.map +1 -0
  30. package/dist/st/workers/assets/miden_client_web.wasm +0 -0
  31. package/dist/st/workers/web-client-methods-worker.js +316 -98
  32. package/dist/st/workers/web-client-methods-worker.js.map +1 -1
  33. package/dist/st/workers/web-client-methods-worker.module.js +1 -1
  34. package/dist/st/workers/web-client-methods-worker.module.js.map +1 -1
  35. package/js/node/napi-compat.js +2 -2
  36. package/js/node-index.js +1 -4
  37. package/js/resources/accounts.js +2 -14
  38. package/js/utils.js +2 -31
  39. package/package.json +4 -4
  40. package/dist/mt/Cargo-C9UbiAcT.js.map +0 -1
  41. package/dist/mt/workers/Cargo-C9UbiAcT-Z344cyB1.js.map +0 -1
  42. package/dist/st/Cargo-OZMlHpic.js.map +0 -1
  43. package/dist/st/workers/Cargo-OZMlHpic-DZjvJlWc.js.map +0 -1
package/dist/mt/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, NetworkNoteStatusInfo, NetworkType, Note, NoteAndArgs, NoteAndArgsArray, NoteArray, NoteAssets, NoteAttachment, 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, StorageMapEntryJs, 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, initThreadPool, mtProbeAsync, mtProbeSync, parallelSumBench, rayonThreadCount, sequentialSumBench, setupLogging, wbg_rayon_PoolBuilder, wbg_rayon_start_worker } from './Cargo-C9UbiAcT.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, JsSettingMutation, JsStateSyncUpdate, JsStorageMapEntry, JsStorageSlot, JsVaultAsset, Library, MerklePath, NetworkId, NetworkNoteStatusInfo, NetworkType, Note, NoteAndArgs, NoteAndArgsArray, NoteArray, NoteAssets, NoteAttachment, 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, StorageMapEntryJs, 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, initThreadPool, mtProbeAsync, mtProbeSync, parallelSumBench, rayonThreadCount, sequentialSumBench, setupLogging, wbg_rayon_PoolBuilder, wbg_rayon_start_worker } from './Cargo-1zqmsGGR.js';
3
3
 
4
4
  const WorkerAction = Object.freeze({
5
5
  INIT: "init",
@@ -224,7 +224,7 @@ function resolveNoteType(type, wasm) {
224
224
  /**
225
225
  * Resolves a storage mode string to a WASM AccountStorageMode instance.
226
226
  *
227
- * @param {string | undefined} mode - "private", "public", or "network". Defaults to "private".
227
+ * @param {string | undefined} mode - "private" or "public". Defaults to "private".
228
228
  * @param {object} wasm - The WASM module.
229
229
  * @returns {AccountStorageMode} The storage mode instance.
230
230
  */
@@ -232,15 +232,13 @@ function resolveStorageMode(mode, wasm) {
232
232
  switch (mode) {
233
233
  case "public":
234
234
  return wasm.AccountStorageMode.public();
235
- case "network":
236
- return wasm.AccountStorageMode.network();
237
235
  case "private":
238
236
  case undefined:
239
237
  case null:
240
238
  return wasm.AccountStorageMode.private();
241
239
  default:
242
240
  throw new Error(
243
- `Unknown storage mode: "${mode}". Expected "private", "public", or "network".`
241
+ `Unknown storage mode: "${mode}". Expected "private" or "public".`
244
242
  );
245
243
  }
246
244
  }
@@ -264,33 +262,6 @@ function resolveAuthScheme(scheme, wasm) {
264
262
  );
265
263
  }
266
264
 
267
- /**
268
- * Resolves an AccountType value to a boolean `mutable` flag
269
- * for the underlying WASM `newWallet()` / `importPublicAccountFromSeed()` calls.
270
- *
271
- * Accepts the numeric WASM enum values (2 = immutable, 3 = mutable) or the
272
- * legacy string aliases ("MutableWallet", "ImmutableWallet"). Defaults to
273
- * mutable when undefined.
274
- *
275
- * @param {number | string | undefined} accountType
276
- * @returns {boolean} Whether the account code is mutable.
277
- */
278
- function resolveAccountMutability(accountType) {
279
- if (
280
- accountType == null ||
281
- accountType === "MutableWallet" ||
282
- accountType === 3
283
- ) {
284
- return true;
285
- }
286
- if (accountType === "ImmutableWallet" || accountType === 2) {
287
- return false;
288
- }
289
- throw new Error(
290
- `Unknown wallet account type: "${accountType}". Expected AccountType.MutableWallet (3) or AccountType.ImmutableWallet (2).`
291
- );
292
- }
293
-
294
265
  /**
295
266
  * Resolves a NoteInput (string | NoteId | InputNoteRecord | Note) to a hex string.
296
267
  *
@@ -413,17 +384,11 @@ class AccountsResource {
413
384
  ) {
414
385
  return await this.#createContract(opts, wasm);
415
386
  } else {
416
- // Default: wallet (mutable or immutable based on type)
417
- const mutable = resolveAccountMutability(opts?.type);
387
+ // Default: wallet
418
388
  const storageMode = resolveStorageMode(opts?.storage ?? "private", wasm);
419
389
  const authScheme = resolveAuthScheme(opts?.auth, wasm);
420
390
  const seed = opts?.seed ? await hashSeed(opts.seed) : undefined;
421
- return await this.#inner.newWallet(
422
- storageMode,
423
- mutable,
424
- authScheme,
425
- seed
426
- );
391
+ return await this.#inner.newWallet(storageMode, authScheme, seed);
427
392
  }
428
393
  }
429
394
 
@@ -433,9 +398,6 @@ class AccountsResource {
433
398
  if (!opts.auth)
434
399
  throw new Error("Contract creation requires an 'auth' (AuthSecretKey)");
435
400
 
436
- // The 0.15 protocol has no code-mutability distinction, so the `type`
437
- // ("ImmutableContract" / "MutableContract") only steers routing here; the
438
- // account's on-chain visibility is set entirely by `storageMode`.
439
401
  const storageMode = resolveStorageMode(opts.storage ?? "public", wasm);
440
402
  const authComponent =
441
403
  wasm.AccountComponent.createAuthComponentFromSecretKey(opts.auth);
@@ -549,10 +511,8 @@ class AccountsResource {
549
511
  if (input.seed) {
550
512
  // Import public account from seed
551
513
  const authScheme = resolveAuthScheme(input.auth, wasm);
552
- const mutable = resolveAccountMutability(input.type);
553
514
  return await this.#inner.importPublicAccountFromSeed(
554
515
  input.seed,
555
- mutable,
556
516
  authScheme
557
517
  );
558
518
  }
@@ -2508,16 +2468,9 @@ function installStorageView(wasmModule) {
2508
2468
  }
2509
2469
 
2510
2470
  const AccountType = Object.freeze({
2511
- // WASM-compatible numeric values usable with AccountBuilder directly
2471
+ // Faucet-kind selectors for accounts.create({ type }).
2512
2472
  FungibleFaucet: 0,
2513
2473
  NonFungibleFaucet: 1,
2514
- RegularAccountImmutableCode: 2,
2515
- RegularAccountUpdatableCode: 3,
2516
- // SDK-friendly aliases (same numeric values as their WASM equivalents)
2517
- MutableWallet: 3,
2518
- ImmutableWallet: 2,
2519
- ImmutableContract: 2,
2520
- MutableContract: 3,
2521
2474
  });
2522
2475
 
2523
2476
  const AuthScheme = Object.freeze({
@@ -2540,6 +2493,34 @@ const Linking = Object.freeze({
2540
2493
  Static: "static",
2541
2494
  });
2542
2495
 
2496
+ // Method classification sets — used by scripts/check-method-classification.js to ensure
2497
+ // every WASM export is explicitly categorised. Update when adding new WASM methods.
2498
+ //
2499
+ // Naming note: "SYNC_METHODS" is a historical misnomer. This set groups methods
2500
+ // that are forwarded transparently to the underlying WASM via the Proxy in
2501
+ // `createClientProxy` — meaning they don't need an explicit JS-class wrapper
2502
+ // here. It does NOT mean "the method is synchronous"; several entries
2503
+ // (e.g. newSwapTransactionRequest, newPswapCreateTransactionRequest) are
2504
+ // `async fn` in Rust because they take the client's RNG via an async lock.
2505
+ const SYNC_METHODS = new Set([
2506
+ "buildSwapTag",
2507
+ "createCodeBuilder",
2508
+ "lastAuthError",
2509
+ "newConsumeTransactionRequest",
2510
+ "newMintTransactionRequest",
2511
+ "newPswapCancelTransactionRequest",
2512
+ "newPswapConsumeTransactionRequest",
2513
+ "newPswapCreateTransactionRequest",
2514
+ "newSendTransactionRequest",
2515
+ "newSwapTransactionRequest",
2516
+ "proveBlock",
2517
+ "serializeMockChain",
2518
+ "serializeMockNoteTransportNode",
2519
+ "setDebugMode",
2520
+ "storeIdentifier",
2521
+ "usesMockChain",
2522
+ ]);
2523
+
2543
2524
  const MOCK_STORE_NAME = "mock_client_db";
2544
2525
 
2545
2526
  const buildTypedArraysExport = (exportObject) => {
@@ -2653,7 +2634,19 @@ function createClientProxy(instance) {
2653
2634
  if (target.wasmWebClient && prop in target.wasmWebClient) {
2654
2635
  const value = target.wasmWebClient[prop];
2655
2636
  if (typeof value === "function") {
2656
- return value.bind(target.wasmWebClient);
2637
+ // SYNC_METHODS are safe to bind raw (synchronous in JS, or
2638
+ // documented exceptions). Everything else holds the WASM
2639
+ // client's internal RefCell across its awaits, so it MUST join
2640
+ // `_serializeWasmCall` — an unserialized fallback overlapping
2641
+ // any in-flight call panics with "RefCell already borrowed"
2642
+ // and poisons the instance for every later call.
2643
+ if (typeof prop === "string" && SYNC_METHODS.has(prop)) {
2644
+ return value.bind(target.wasmWebClient);
2645
+ }
2646
+ return (...args) =>
2647
+ target._serializeWasmCall(() =>
2648
+ value.apply(target.wasmWebClient, args)
2649
+ );
2657
2650
  }
2658
2651
  return value;
2659
2652
  }
@@ -3182,15 +3175,10 @@ class WebClient {
3182
3175
 
3183
3176
  // ----- Explicitly Wrapped Methods (Worker-Forwarded) -----
3184
3177
 
3185
- async newWallet(storageMode, mutable, authSchemeId, seed) {
3178
+ async newWallet(storageMode, authSchemeId, seed) {
3186
3179
  return this._serializeWasmCall(async () => {
3187
3180
  const wasmWebClient = await this.getWasmWebClient();
3188
- return await wasmWebClient.newWallet(
3189
- storageMode,
3190
- mutable,
3191
- authSchemeId,
3192
- seed
3193
- );
3181
+ return await wasmWebClient.newWallet(storageMode, authSchemeId, seed);
3194
3182
  });
3195
3183
  }
3196
3184
 
@@ -3232,147 +3220,160 @@ class WebClient {
3232
3220
  }
3233
3221
 
3234
3222
  async submitNewTransaction(accountId, transactionRequest) {
3235
- try {
3236
- if (!this.worker) {
3237
- const wasmWebClient = await this.getWasmWebClient();
3238
- return await wasmWebClient.submitNewTransaction(
3239
- accountId,
3240
- transactionRequest
3241
- );
3242
- }
3223
+ return this._serializeWasmCall(async () => {
3224
+ try {
3225
+ if (!this.worker) {
3226
+ const wasmWebClient = await this.getWasmWebClient();
3227
+ return await wasmWebClient.submitNewTransaction(
3228
+ accountId,
3229
+ transactionRequest
3230
+ );
3231
+ }
3243
3232
 
3244
- const wasm = await getWasmOrThrow();
3245
- const serializedTransactionRequest = transactionRequest.serialize();
3246
- const result = await this.callMethodWithWorker(
3247
- MethodName.SUBMIT_NEW_TRANSACTION,
3248
- accountId.toString(),
3249
- serializedTransactionRequest
3250
- );
3233
+ const wasm = await getWasmOrThrow();
3234
+ const serializedTransactionRequest = transactionRequest.serialize();
3235
+ const result = await this.callMethodWithWorker(
3236
+ MethodName.SUBMIT_NEW_TRANSACTION,
3237
+ accountId.toString(),
3238
+ serializedTransactionRequest
3239
+ );
3251
3240
 
3252
- const transactionResult = wasm.TransactionResult.deserialize(
3253
- new Uint8Array(result.serializedTransactionResult)
3254
- );
3241
+ const transactionResult = wasm.TransactionResult.deserialize(
3242
+ new Uint8Array(result.serializedTransactionResult)
3243
+ );
3255
3244
 
3256
- return transactionResult.id();
3257
- } catch (error) {
3258
- console.error("INDEX.JS: Error in submitNewTransaction:", error);
3259
- throw error;
3260
- }
3245
+ return transactionResult.id();
3246
+ } catch (error) {
3247
+ console.error("INDEX.JS: Error in submitNewTransaction:", error);
3248
+ throw error;
3249
+ }
3250
+ });
3261
3251
  }
3262
3252
 
3263
3253
  async submitNewTransactionWithProver(accountId, transactionRequest, prover) {
3264
- try {
3265
- if (!this.worker) {
3266
- const wasmWebClient = await this.getWasmWebClient();
3267
- return await wasmWebClient.submitNewTransactionWithProver(
3268
- accountId,
3269
- transactionRequest,
3270
- prover
3271
- );
3272
- }
3254
+ return this._serializeWasmCall(async () => {
3255
+ try {
3256
+ if (!this.worker) {
3257
+ const wasmWebClient = await this.getWasmWebClient();
3258
+ return await wasmWebClient.submitNewTransactionWithProver(
3259
+ accountId,
3260
+ transactionRequest,
3261
+ prover
3262
+ );
3263
+ }
3273
3264
 
3274
- const wasm = await getWasmOrThrow();
3275
- const serializedTransactionRequest = transactionRequest.serialize();
3276
- const proverPayload = prover.serialize();
3277
- const result = await this.callMethodWithWorker(
3278
- MethodName.SUBMIT_NEW_TRANSACTION_WITH_PROVER,
3279
- accountId.toString(),
3280
- serializedTransactionRequest,
3281
- proverPayload
3282
- );
3265
+ const wasm = await getWasmOrThrow();
3266
+ const serializedTransactionRequest = transactionRequest.serialize();
3267
+ const proverPayload = prover.serialize();
3268
+ const result = await this.callMethodWithWorker(
3269
+ MethodName.SUBMIT_NEW_TRANSACTION_WITH_PROVER,
3270
+ accountId.toString(),
3271
+ serializedTransactionRequest,
3272
+ proverPayload
3273
+ );
3283
3274
 
3284
- const transactionResult = wasm.TransactionResult.deserialize(
3285
- new Uint8Array(result.serializedTransactionResult)
3286
- );
3275
+ const transactionResult = wasm.TransactionResult.deserialize(
3276
+ new Uint8Array(result.serializedTransactionResult)
3277
+ );
3287
3278
 
3288
- return transactionResult.id();
3289
- } catch (error) {
3290
- console.error(
3291
- "INDEX.JS: Error in submitNewTransactionWithProver:",
3292
- error
3293
- );
3294
- throw error;
3295
- }
3279
+ return transactionResult.id();
3280
+ } catch (error) {
3281
+ console.error(
3282
+ "INDEX.JS: Error in submitNewTransactionWithProver:",
3283
+ error
3284
+ );
3285
+ throw error;
3286
+ }
3287
+ });
3296
3288
  }
3297
3289
 
3298
3290
  async executeTransaction(accountId, transactionRequest) {
3299
- try {
3300
- if (!this.worker) {
3301
- const wasmWebClient = await this.getWasmWebClient();
3302
- return await wasmWebClient.executeTransaction(
3303
- accountId,
3304
- transactionRequest
3305
- );
3306
- }
3291
+ return this._serializeWasmCall(async () => {
3292
+ try {
3293
+ if (!this.worker) {
3294
+ const wasmWebClient = await this.getWasmWebClient();
3295
+ return await wasmWebClient.executeTransaction(
3296
+ accountId,
3297
+ transactionRequest
3298
+ );
3299
+ }
3307
3300
 
3308
- const wasm = await getWasmOrThrow();
3309
- const serializedTransactionRequest = transactionRequest.serialize();
3310
- const serializedResultBytes = await this.callMethodWithWorker(
3311
- MethodName.EXECUTE_TRANSACTION,
3312
- accountId.toString(),
3313
- serializedTransactionRequest
3314
- );
3301
+ const wasm = await getWasmOrThrow();
3302
+ const serializedTransactionRequest = transactionRequest.serialize();
3303
+ const serializedResultBytes = await this.callMethodWithWorker(
3304
+ MethodName.EXECUTE_TRANSACTION,
3305
+ accountId.toString(),
3306
+ serializedTransactionRequest
3307
+ );
3315
3308
 
3316
- return wasm.TransactionResult.deserialize(
3317
- new Uint8Array(serializedResultBytes)
3318
- );
3319
- } catch (error) {
3320
- console.error("INDEX.JS: Error in executeTransaction:", error);
3321
- throw error;
3322
- }
3309
+ return wasm.TransactionResult.deserialize(
3310
+ new Uint8Array(serializedResultBytes)
3311
+ );
3312
+ } catch (error) {
3313
+ console.error("INDEX.JS: Error in executeTransaction:", error);
3314
+ throw error;
3315
+ }
3316
+ });
3323
3317
  }
3324
3318
 
3325
3319
  async proveTransaction(transactionResult, prover) {
3326
- try {
3327
- if (!this.worker) {
3328
- const wasmWebClient = await this.getWasmWebClient();
3329
- return await wasmWebClient.proveTransaction(transactionResult, prover);
3330
- }
3320
+ return this._serializeWasmCall(async () => {
3321
+ try {
3322
+ if (!this.worker) {
3323
+ const wasmWebClient = await this.getWasmWebClient();
3324
+ return await wasmWebClient.proveTransaction(
3325
+ transactionResult,
3326
+ prover
3327
+ );
3328
+ }
3331
3329
 
3332
- const wasm = await getWasmOrThrow();
3333
- const serializedTransactionResult = transactionResult.serialize();
3334
- const proverPayload = prover ? prover.serialize() : null;
3330
+ const wasm = await getWasmOrThrow();
3331
+ const serializedTransactionResult = transactionResult.serialize();
3332
+ const proverPayload = prover ? prover.serialize() : null;
3335
3333
 
3336
- const serializedProvenBytes = await this.callMethodWithWorker(
3337
- MethodName.PROVE_TRANSACTION,
3338
- serializedTransactionResult,
3339
- proverPayload
3340
- );
3334
+ const serializedProvenBytes = await this.callMethodWithWorker(
3335
+ MethodName.PROVE_TRANSACTION,
3336
+ serializedTransactionResult,
3337
+ proverPayload
3338
+ );
3341
3339
 
3342
- return wasm.ProvenTransaction.deserialize(
3343
- new Uint8Array(serializedProvenBytes)
3344
- );
3345
- } catch (error) {
3346
- console.error("INDEX.JS: Error in proveTransaction:", error);
3347
- throw error;
3348
- }
3340
+ return wasm.ProvenTransaction.deserialize(
3341
+ new Uint8Array(serializedProvenBytes)
3342
+ );
3343
+ } catch (error) {
3344
+ console.error("INDEX.JS: Error in proveTransaction:", error);
3345
+ throw error;
3346
+ }
3347
+ });
3349
3348
  }
3350
3349
 
3351
3350
  async applyTransaction(transactionResult, submissionHeight) {
3352
- try {
3353
- if (!this.worker) {
3354
- const wasmWebClient = await this.getWasmWebClient();
3355
- return await wasmWebClient.applyTransaction(
3356
- transactionResult,
3351
+ return this._serializeWasmCall(async () => {
3352
+ try {
3353
+ if (!this.worker) {
3354
+ const wasmWebClient = await this.getWasmWebClient();
3355
+ return await wasmWebClient.applyTransaction(
3356
+ transactionResult,
3357
+ submissionHeight
3358
+ );
3359
+ }
3360
+
3361
+ const wasm = await getWasmOrThrow();
3362
+ const serializedTransactionResult = transactionResult.serialize();
3363
+ const serializedUpdateBytes = await this.callMethodWithWorker(
3364
+ MethodName.APPLY_TRANSACTION,
3365
+ serializedTransactionResult,
3357
3366
  submissionHeight
3358
3367
  );
3359
- }
3360
-
3361
- const wasm = await getWasmOrThrow();
3362
- const serializedTransactionResult = transactionResult.serialize();
3363
- const serializedUpdateBytes = await this.callMethodWithWorker(
3364
- MethodName.APPLY_TRANSACTION,
3365
- serializedTransactionResult,
3366
- submissionHeight
3367
- );
3368
3368
 
3369
- return wasm.TransactionStoreUpdate.deserialize(
3370
- new Uint8Array(serializedUpdateBytes)
3371
- );
3372
- } catch (error) {
3373
- console.error("INDEX.JS: Error in applyTransaction:", error);
3374
- throw error;
3375
- }
3369
+ return wasm.TransactionStoreUpdate.deserialize(
3370
+ new Uint8Array(serializedUpdateBytes)
3371
+ );
3372
+ } catch (error) {
3373
+ console.error("INDEX.JS: Error in applyTransaction:", error);
3374
+ throw error;
3375
+ }
3376
+ });
3376
3377
  }
3377
3378
 
3378
3379
  /**
@@ -3389,18 +3390,24 @@ class WebClient {
3389
3390
  const methodId = MethodName.SYNC_STATE;
3390
3391
 
3391
3392
  try {
3392
- return await withSyncLock(dbId, methodId, async () => {
3393
- if (!this.worker) {
3394
- const wasmWebClient = await this.getWasmWebClient();
3395
- return await wasmWebClient.syncStateImpl();
3396
- }
3397
- const wasm = await getWasmOrThrow();
3398
- const serializedSyncSummaryBytes =
3399
- await this.callMethodWithWorker(methodId);
3400
- return wasm.SyncSummary.deserialize(
3401
- new Uint8Array(serializedSyncSummaryBytes)
3402
- );
3403
- });
3393
+ // The sync lock coalesces concurrent sync callers; the inner
3394
+ // `_serializeWasmCall` keeps the WASM phase from racing any other
3395
+ // serialized method on this instance. Lock order is always
3396
+ // sync lock → chain, so the two can't deadlock.
3397
+ return await withSyncLock(dbId, methodId, async () =>
3398
+ this._serializeWasmCall(async () => {
3399
+ if (!this.worker) {
3400
+ const wasmWebClient = await this.getWasmWebClient();
3401
+ return await wasmWebClient.syncStateImpl();
3402
+ }
3403
+ const wasm = await getWasmOrThrow();
3404
+ const serializedSyncSummaryBytes =
3405
+ await this.callMethodWithWorker(methodId);
3406
+ return wasm.SyncSummary.deserialize(
3407
+ new Uint8Array(serializedSyncSummaryBytes)
3408
+ );
3409
+ })
3410
+ );
3404
3411
  } catch (error) {
3405
3412
  console.error("INDEX.JS: Error in syncState:", error);
3406
3413
  throw error;
@@ -3417,14 +3424,16 @@ class WebClient {
3417
3424
  const methodId = MethodName.SYNC_NOTE_TRANSPORT;
3418
3425
 
3419
3426
  try {
3420
- await withSyncLock(dbId, methodId, async () => {
3421
- if (!this.worker) {
3422
- const wasmWebClient = await this.getWasmWebClient();
3423
- await wasmWebClient.syncNoteTransportImpl();
3424
- } else {
3425
- await this.callMethodWithWorker(methodId);
3426
- }
3427
- });
3427
+ await withSyncLock(dbId, methodId, async () =>
3428
+ this._serializeWasmCall(async () => {
3429
+ if (!this.worker) {
3430
+ const wasmWebClient = await this.getWasmWebClient();
3431
+ await wasmWebClient.syncNoteTransportImpl();
3432
+ } else {
3433
+ await this.callMethodWithWorker(methodId);
3434
+ }
3435
+ })
3436
+ );
3428
3437
  } catch (error) {
3429
3438
  console.error("INDEX.JS: Error in syncNoteTransport:", error);
3430
3439
  throw error;
@@ -3441,18 +3450,20 @@ class WebClient {
3441
3450
  const methodId = MethodName.SYNC_CHAIN;
3442
3451
 
3443
3452
  try {
3444
- return await withSyncLock(dbId, methodId, async () => {
3445
- if (!this.worker) {
3446
- const wasmWebClient = await this.getWasmWebClient();
3447
- return await wasmWebClient.syncChainImpl();
3448
- }
3449
- const wasm = await getWasmOrThrow();
3450
- const serializedSyncSummaryBytes =
3451
- await this.callMethodWithWorker(methodId);
3452
- return wasm.SyncSummary.deserialize(
3453
- new Uint8Array(serializedSyncSummaryBytes)
3454
- );
3455
- });
3453
+ return await withSyncLock(dbId, methodId, async () =>
3454
+ this._serializeWasmCall(async () => {
3455
+ if (!this.worker) {
3456
+ const wasmWebClient = await this.getWasmWebClient();
3457
+ return await wasmWebClient.syncChainImpl();
3458
+ }
3459
+ const wasm = await getWasmOrThrow();
3460
+ const serializedSyncSummaryBytes =
3461
+ await this.callMethodWithWorker(methodId);
3462
+ return wasm.SyncSummary.deserialize(
3463
+ new Uint8Array(serializedSyncSummaryBytes)
3464
+ );
3465
+ })
3466
+ );
3456
3467
  } catch (error) {
3457
3468
  console.error("INDEX.JS: Error in syncChain:", error);
3458
3469
  throw error;
@@ -3561,29 +3572,31 @@ class MockWebClient extends WebClient {
3561
3572
  const methodId = MethodName.SYNC_STATE;
3562
3573
 
3563
3574
  try {
3564
- return await withSyncLock(dbId, methodId, async () => {
3565
- const wasmWebClient = await this.getWasmWebClient();
3566
-
3567
- if (!this.worker) {
3568
- return await wasmWebClient.syncStateImpl();
3569
- }
3575
+ return await withSyncLock(dbId, methodId, async () =>
3576
+ this._serializeWasmCall(async () => {
3577
+ const wasmWebClient = await this.getWasmWebClient();
3570
3578
 
3571
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3572
- .buffer;
3573
- const serializedMockNoteTransportNode = (
3574
- await wasmWebClient.serializeMockNoteTransportNode()
3575
- ).buffer;
3579
+ if (!this.worker) {
3580
+ return await wasmWebClient.syncStateImpl();
3581
+ }
3576
3582
 
3577
- const wasm = await getWasmOrThrow();
3578
- const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3579
- MethodName.SYNC_STATE_MOCK,
3580
- serializedMockChain,
3581
- serializedMockNoteTransportNode
3582
- );
3583
- return wasm.SyncSummary.deserialize(
3584
- new Uint8Array(serializedSyncSummaryBytes)
3585
- );
3586
- });
3583
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3584
+ .buffer;
3585
+ const serializedMockNoteTransportNode = (
3586
+ await wasmWebClient.serializeMockNoteTransportNode()
3587
+ ).buffer;
3588
+
3589
+ const wasm = await getWasmOrThrow();
3590
+ const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3591
+ MethodName.SYNC_STATE_MOCK,
3592
+ serializedMockChain,
3593
+ serializedMockNoteTransportNode
3594
+ );
3595
+ return wasm.SyncSummary.deserialize(
3596
+ new Uint8Array(serializedSyncSummaryBytes)
3597
+ );
3598
+ })
3599
+ );
3587
3600
  } catch (error) {
3588
3601
  console.error("INDEX.JS: Error in syncState:", error);
3589
3602
  throw error;
@@ -3605,29 +3618,31 @@ class MockWebClient extends WebClient {
3605
3618
  const methodId = MethodName.SYNC_CHAIN;
3606
3619
 
3607
3620
  try {
3608
- return await withSyncLock(dbId, methodId, async () => {
3609
- const wasmWebClient = await this.getWasmWebClient();
3610
-
3611
- if (!this.worker) {
3612
- return await wasmWebClient.syncChainImpl();
3613
- }
3621
+ return await withSyncLock(dbId, methodId, async () =>
3622
+ this._serializeWasmCall(async () => {
3623
+ const wasmWebClient = await this.getWasmWebClient();
3614
3624
 
3615
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3616
- .buffer;
3617
- const serializedMockNoteTransportNode = (
3618
- await wasmWebClient.serializeMockNoteTransportNode()
3619
- ).buffer;
3625
+ if (!this.worker) {
3626
+ return await wasmWebClient.syncChainImpl();
3627
+ }
3620
3628
 
3621
- const wasm = await getWasmOrThrow();
3622
- const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3623
- MethodName.SYNC_CHAIN_MOCK,
3624
- serializedMockChain,
3625
- serializedMockNoteTransportNode
3626
- );
3627
- return wasm.SyncSummary.deserialize(
3628
- new Uint8Array(serializedSyncSummaryBytes)
3629
- );
3630
- });
3629
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3630
+ .buffer;
3631
+ const serializedMockNoteTransportNode = (
3632
+ await wasmWebClient.serializeMockNoteTransportNode()
3633
+ ).buffer;
3634
+
3635
+ const wasm = await getWasmOrThrow();
3636
+ const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3637
+ MethodName.SYNC_CHAIN_MOCK,
3638
+ serializedMockChain,
3639
+ serializedMockNoteTransportNode
3640
+ );
3641
+ return wasm.SyncSummary.deserialize(
3642
+ new Uint8Array(serializedSyncSummaryBytes)
3643
+ );
3644
+ })
3645
+ );
3631
3646
  } catch (error) {
3632
3647
  console.error("INDEX.JS: Error in syncChain:", error);
3633
3648
  throw error;
@@ -3648,26 +3663,28 @@ class MockWebClient extends WebClient {
3648
3663
  const methodId = MethodName.SYNC_NOTE_TRANSPORT;
3649
3664
 
3650
3665
  try {
3651
- await withSyncLock(dbId, methodId, async () => {
3652
- const wasmWebClient = await this.getWasmWebClient();
3666
+ await withSyncLock(dbId, methodId, async () =>
3667
+ this._serializeWasmCall(async () => {
3668
+ const wasmWebClient = await this.getWasmWebClient();
3653
3669
 
3654
- if (!this.worker) {
3655
- await wasmWebClient.syncNoteTransportImpl();
3656
- return;
3657
- }
3670
+ if (!this.worker) {
3671
+ await wasmWebClient.syncNoteTransportImpl();
3672
+ return;
3673
+ }
3658
3674
 
3659
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3660
- .buffer;
3661
- const serializedMockNoteTransportNode = (
3662
- await wasmWebClient.serializeMockNoteTransportNode()
3663
- ).buffer;
3675
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3676
+ .buffer;
3677
+ const serializedMockNoteTransportNode = (
3678
+ await wasmWebClient.serializeMockNoteTransportNode()
3679
+ ).buffer;
3664
3680
 
3665
- await this.callMethodWithWorker(
3666
- MethodName.SYNC_NOTE_TRANSPORT_MOCK,
3667
- serializedMockChain,
3668
- serializedMockNoteTransportNode
3669
- );
3670
- });
3681
+ await this.callMethodWithWorker(
3682
+ MethodName.SYNC_NOTE_TRANSPORT_MOCK,
3683
+ serializedMockChain,
3684
+ serializedMockNoteTransportNode
3685
+ );
3686
+ })
3687
+ );
3671
3688
  } catch (error) {
3672
3689
  console.error("INDEX.JS: Error in syncNoteTransport:", error);
3673
3690
  throw error;