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

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.
package/dist/mt/index.js CHANGED
@@ -2540,6 +2540,34 @@ const Linking = Object.freeze({
2540
2540
  Static: "static",
2541
2541
  });
2542
2542
 
2543
+ // Method classification sets — used by scripts/check-method-classification.js to ensure
2544
+ // every WASM export is explicitly categorised. Update when adding new WASM methods.
2545
+ //
2546
+ // Naming note: "SYNC_METHODS" is a historical misnomer. This set groups methods
2547
+ // that are forwarded transparently to the underlying WASM via the Proxy in
2548
+ // `createClientProxy` — meaning they don't need an explicit JS-class wrapper
2549
+ // here. It does NOT mean "the method is synchronous"; several entries
2550
+ // (e.g. newSwapTransactionRequest, newPswapCreateTransactionRequest) are
2551
+ // `async fn` in Rust because they take the client's RNG via an async lock.
2552
+ const SYNC_METHODS = new Set([
2553
+ "buildSwapTag",
2554
+ "createCodeBuilder",
2555
+ "lastAuthError",
2556
+ "newConsumeTransactionRequest",
2557
+ "newMintTransactionRequest",
2558
+ "newPswapCancelTransactionRequest",
2559
+ "newPswapConsumeTransactionRequest",
2560
+ "newPswapCreateTransactionRequest",
2561
+ "newSendTransactionRequest",
2562
+ "newSwapTransactionRequest",
2563
+ "proveBlock",
2564
+ "serializeMockChain",
2565
+ "serializeMockNoteTransportNode",
2566
+ "setDebugMode",
2567
+ "storeIdentifier",
2568
+ "usesMockChain",
2569
+ ]);
2570
+
2543
2571
  const MOCK_STORE_NAME = "mock_client_db";
2544
2572
 
2545
2573
  const buildTypedArraysExport = (exportObject) => {
@@ -2653,7 +2681,19 @@ function createClientProxy(instance) {
2653
2681
  if (target.wasmWebClient && prop in target.wasmWebClient) {
2654
2682
  const value = target.wasmWebClient[prop];
2655
2683
  if (typeof value === "function") {
2656
- return value.bind(target.wasmWebClient);
2684
+ // SYNC_METHODS are safe to bind raw (synchronous in JS, or
2685
+ // documented exceptions). Everything else holds the WASM
2686
+ // client's internal RefCell across its awaits, so it MUST join
2687
+ // `_serializeWasmCall` — an unserialized fallback overlapping
2688
+ // any in-flight call panics with "RefCell already borrowed"
2689
+ // and poisons the instance for every later call.
2690
+ if (typeof prop === "string" && SYNC_METHODS.has(prop)) {
2691
+ return value.bind(target.wasmWebClient);
2692
+ }
2693
+ return (...args) =>
2694
+ target._serializeWasmCall(() =>
2695
+ value.apply(target.wasmWebClient, args)
2696
+ );
2657
2697
  }
2658
2698
  return value;
2659
2699
  }
@@ -3232,147 +3272,160 @@ class WebClient {
3232
3272
  }
3233
3273
 
3234
3274
  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
- }
3275
+ return this._serializeWasmCall(async () => {
3276
+ try {
3277
+ if (!this.worker) {
3278
+ const wasmWebClient = await this.getWasmWebClient();
3279
+ return await wasmWebClient.submitNewTransaction(
3280
+ accountId,
3281
+ transactionRequest
3282
+ );
3283
+ }
3243
3284
 
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
- );
3285
+ const wasm = await getWasmOrThrow();
3286
+ const serializedTransactionRequest = transactionRequest.serialize();
3287
+ const result = await this.callMethodWithWorker(
3288
+ MethodName.SUBMIT_NEW_TRANSACTION,
3289
+ accountId.toString(),
3290
+ serializedTransactionRequest
3291
+ );
3251
3292
 
3252
- const transactionResult = wasm.TransactionResult.deserialize(
3253
- new Uint8Array(result.serializedTransactionResult)
3254
- );
3293
+ const transactionResult = wasm.TransactionResult.deserialize(
3294
+ new Uint8Array(result.serializedTransactionResult)
3295
+ );
3255
3296
 
3256
- return transactionResult.id();
3257
- } catch (error) {
3258
- console.error("INDEX.JS: Error in submitNewTransaction:", error);
3259
- throw error;
3260
- }
3297
+ return transactionResult.id();
3298
+ } catch (error) {
3299
+ console.error("INDEX.JS: Error in submitNewTransaction:", error);
3300
+ throw error;
3301
+ }
3302
+ });
3261
3303
  }
3262
3304
 
3263
3305
  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
- }
3306
+ return this._serializeWasmCall(async () => {
3307
+ try {
3308
+ if (!this.worker) {
3309
+ const wasmWebClient = await this.getWasmWebClient();
3310
+ return await wasmWebClient.submitNewTransactionWithProver(
3311
+ accountId,
3312
+ transactionRequest,
3313
+ prover
3314
+ );
3315
+ }
3273
3316
 
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
- );
3317
+ const wasm = await getWasmOrThrow();
3318
+ const serializedTransactionRequest = transactionRequest.serialize();
3319
+ const proverPayload = prover.serialize();
3320
+ const result = await this.callMethodWithWorker(
3321
+ MethodName.SUBMIT_NEW_TRANSACTION_WITH_PROVER,
3322
+ accountId.toString(),
3323
+ serializedTransactionRequest,
3324
+ proverPayload
3325
+ );
3283
3326
 
3284
- const transactionResult = wasm.TransactionResult.deserialize(
3285
- new Uint8Array(result.serializedTransactionResult)
3286
- );
3327
+ const transactionResult = wasm.TransactionResult.deserialize(
3328
+ new Uint8Array(result.serializedTransactionResult)
3329
+ );
3287
3330
 
3288
- return transactionResult.id();
3289
- } catch (error) {
3290
- console.error(
3291
- "INDEX.JS: Error in submitNewTransactionWithProver:",
3292
- error
3293
- );
3294
- throw error;
3295
- }
3331
+ return transactionResult.id();
3332
+ } catch (error) {
3333
+ console.error(
3334
+ "INDEX.JS: Error in submitNewTransactionWithProver:",
3335
+ error
3336
+ );
3337
+ throw error;
3338
+ }
3339
+ });
3296
3340
  }
3297
3341
 
3298
3342
  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
- }
3343
+ return this._serializeWasmCall(async () => {
3344
+ try {
3345
+ if (!this.worker) {
3346
+ const wasmWebClient = await this.getWasmWebClient();
3347
+ return await wasmWebClient.executeTransaction(
3348
+ accountId,
3349
+ transactionRequest
3350
+ );
3351
+ }
3307
3352
 
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
- );
3353
+ const wasm = await getWasmOrThrow();
3354
+ const serializedTransactionRequest = transactionRequest.serialize();
3355
+ const serializedResultBytes = await this.callMethodWithWorker(
3356
+ MethodName.EXECUTE_TRANSACTION,
3357
+ accountId.toString(),
3358
+ serializedTransactionRequest
3359
+ );
3315
3360
 
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
- }
3361
+ return wasm.TransactionResult.deserialize(
3362
+ new Uint8Array(serializedResultBytes)
3363
+ );
3364
+ } catch (error) {
3365
+ console.error("INDEX.JS: Error in executeTransaction:", error);
3366
+ throw error;
3367
+ }
3368
+ });
3323
3369
  }
3324
3370
 
3325
3371
  async proveTransaction(transactionResult, prover) {
3326
- try {
3327
- if (!this.worker) {
3328
- const wasmWebClient = await this.getWasmWebClient();
3329
- return await wasmWebClient.proveTransaction(transactionResult, prover);
3330
- }
3372
+ return this._serializeWasmCall(async () => {
3373
+ try {
3374
+ if (!this.worker) {
3375
+ const wasmWebClient = await this.getWasmWebClient();
3376
+ return await wasmWebClient.proveTransaction(
3377
+ transactionResult,
3378
+ prover
3379
+ );
3380
+ }
3331
3381
 
3332
- const wasm = await getWasmOrThrow();
3333
- const serializedTransactionResult = transactionResult.serialize();
3334
- const proverPayload = prover ? prover.serialize() : null;
3382
+ const wasm = await getWasmOrThrow();
3383
+ const serializedTransactionResult = transactionResult.serialize();
3384
+ const proverPayload = prover ? prover.serialize() : null;
3335
3385
 
3336
- const serializedProvenBytes = await this.callMethodWithWorker(
3337
- MethodName.PROVE_TRANSACTION,
3338
- serializedTransactionResult,
3339
- proverPayload
3340
- );
3386
+ const serializedProvenBytes = await this.callMethodWithWorker(
3387
+ MethodName.PROVE_TRANSACTION,
3388
+ serializedTransactionResult,
3389
+ proverPayload
3390
+ );
3341
3391
 
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
- }
3392
+ return wasm.ProvenTransaction.deserialize(
3393
+ new Uint8Array(serializedProvenBytes)
3394
+ );
3395
+ } catch (error) {
3396
+ console.error("INDEX.JS: Error in proveTransaction:", error);
3397
+ throw error;
3398
+ }
3399
+ });
3349
3400
  }
3350
3401
 
3351
3402
  async applyTransaction(transactionResult, submissionHeight) {
3352
- try {
3353
- if (!this.worker) {
3354
- const wasmWebClient = await this.getWasmWebClient();
3355
- return await wasmWebClient.applyTransaction(
3356
- transactionResult,
3403
+ return this._serializeWasmCall(async () => {
3404
+ try {
3405
+ if (!this.worker) {
3406
+ const wasmWebClient = await this.getWasmWebClient();
3407
+ return await wasmWebClient.applyTransaction(
3408
+ transactionResult,
3409
+ submissionHeight
3410
+ );
3411
+ }
3412
+
3413
+ const wasm = await getWasmOrThrow();
3414
+ const serializedTransactionResult = transactionResult.serialize();
3415
+ const serializedUpdateBytes = await this.callMethodWithWorker(
3416
+ MethodName.APPLY_TRANSACTION,
3417
+ serializedTransactionResult,
3357
3418
  submissionHeight
3358
3419
  );
3359
- }
3360
3420
 
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
-
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
- }
3421
+ return wasm.TransactionStoreUpdate.deserialize(
3422
+ new Uint8Array(serializedUpdateBytes)
3423
+ );
3424
+ } catch (error) {
3425
+ console.error("INDEX.JS: Error in applyTransaction:", error);
3426
+ throw error;
3427
+ }
3428
+ });
3376
3429
  }
3377
3430
 
3378
3431
  /**
@@ -3389,18 +3442,24 @@ class WebClient {
3389
3442
  const methodId = MethodName.SYNC_STATE;
3390
3443
 
3391
3444
  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
- });
3445
+ // The sync lock coalesces concurrent sync callers; the inner
3446
+ // `_serializeWasmCall` keeps the WASM phase from racing any other
3447
+ // serialized method on this instance. Lock order is always
3448
+ // sync lock → chain, so the two can't deadlock.
3449
+ return await withSyncLock(dbId, methodId, async () =>
3450
+ this._serializeWasmCall(async () => {
3451
+ if (!this.worker) {
3452
+ const wasmWebClient = await this.getWasmWebClient();
3453
+ return await wasmWebClient.syncStateImpl();
3454
+ }
3455
+ const wasm = await getWasmOrThrow();
3456
+ const serializedSyncSummaryBytes =
3457
+ await this.callMethodWithWorker(methodId);
3458
+ return wasm.SyncSummary.deserialize(
3459
+ new Uint8Array(serializedSyncSummaryBytes)
3460
+ );
3461
+ })
3462
+ );
3404
3463
  } catch (error) {
3405
3464
  console.error("INDEX.JS: Error in syncState:", error);
3406
3465
  throw error;
@@ -3417,14 +3476,16 @@ class WebClient {
3417
3476
  const methodId = MethodName.SYNC_NOTE_TRANSPORT;
3418
3477
 
3419
3478
  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
- });
3479
+ await withSyncLock(dbId, methodId, async () =>
3480
+ this._serializeWasmCall(async () => {
3481
+ if (!this.worker) {
3482
+ const wasmWebClient = await this.getWasmWebClient();
3483
+ await wasmWebClient.syncNoteTransportImpl();
3484
+ } else {
3485
+ await this.callMethodWithWorker(methodId);
3486
+ }
3487
+ })
3488
+ );
3428
3489
  } catch (error) {
3429
3490
  console.error("INDEX.JS: Error in syncNoteTransport:", error);
3430
3491
  throw error;
@@ -3441,18 +3502,20 @@ class WebClient {
3441
3502
  const methodId = MethodName.SYNC_CHAIN;
3442
3503
 
3443
3504
  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
- });
3505
+ return await withSyncLock(dbId, methodId, async () =>
3506
+ this._serializeWasmCall(async () => {
3507
+ if (!this.worker) {
3508
+ const wasmWebClient = await this.getWasmWebClient();
3509
+ return await wasmWebClient.syncChainImpl();
3510
+ }
3511
+ const wasm = await getWasmOrThrow();
3512
+ const serializedSyncSummaryBytes =
3513
+ await this.callMethodWithWorker(methodId);
3514
+ return wasm.SyncSummary.deserialize(
3515
+ new Uint8Array(serializedSyncSummaryBytes)
3516
+ );
3517
+ })
3518
+ );
3456
3519
  } catch (error) {
3457
3520
  console.error("INDEX.JS: Error in syncChain:", error);
3458
3521
  throw error;
@@ -3561,29 +3624,31 @@ class MockWebClient extends WebClient {
3561
3624
  const methodId = MethodName.SYNC_STATE;
3562
3625
 
3563
3626
  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
- }
3627
+ return await withSyncLock(dbId, methodId, async () =>
3628
+ this._serializeWasmCall(async () => {
3629
+ const wasmWebClient = await this.getWasmWebClient();
3570
3630
 
3571
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3572
- .buffer;
3573
- const serializedMockNoteTransportNode = (
3574
- await wasmWebClient.serializeMockNoteTransportNode()
3575
- ).buffer;
3631
+ if (!this.worker) {
3632
+ return await wasmWebClient.syncStateImpl();
3633
+ }
3576
3634
 
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
- });
3635
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3636
+ .buffer;
3637
+ const serializedMockNoteTransportNode = (
3638
+ await wasmWebClient.serializeMockNoteTransportNode()
3639
+ ).buffer;
3640
+
3641
+ const wasm = await getWasmOrThrow();
3642
+ const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3643
+ MethodName.SYNC_STATE_MOCK,
3644
+ serializedMockChain,
3645
+ serializedMockNoteTransportNode
3646
+ );
3647
+ return wasm.SyncSummary.deserialize(
3648
+ new Uint8Array(serializedSyncSummaryBytes)
3649
+ );
3650
+ })
3651
+ );
3587
3652
  } catch (error) {
3588
3653
  console.error("INDEX.JS: Error in syncState:", error);
3589
3654
  throw error;
@@ -3605,29 +3670,31 @@ class MockWebClient extends WebClient {
3605
3670
  const methodId = MethodName.SYNC_CHAIN;
3606
3671
 
3607
3672
  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
- }
3673
+ return await withSyncLock(dbId, methodId, async () =>
3674
+ this._serializeWasmCall(async () => {
3675
+ const wasmWebClient = await this.getWasmWebClient();
3614
3676
 
3615
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3616
- .buffer;
3617
- const serializedMockNoteTransportNode = (
3618
- await wasmWebClient.serializeMockNoteTransportNode()
3619
- ).buffer;
3677
+ if (!this.worker) {
3678
+ return await wasmWebClient.syncChainImpl();
3679
+ }
3620
3680
 
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
- });
3681
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3682
+ .buffer;
3683
+ const serializedMockNoteTransportNode = (
3684
+ await wasmWebClient.serializeMockNoteTransportNode()
3685
+ ).buffer;
3686
+
3687
+ const wasm = await getWasmOrThrow();
3688
+ const serializedSyncSummaryBytes = await this.callMethodWithWorker(
3689
+ MethodName.SYNC_CHAIN_MOCK,
3690
+ serializedMockChain,
3691
+ serializedMockNoteTransportNode
3692
+ );
3693
+ return wasm.SyncSummary.deserialize(
3694
+ new Uint8Array(serializedSyncSummaryBytes)
3695
+ );
3696
+ })
3697
+ );
3631
3698
  } catch (error) {
3632
3699
  console.error("INDEX.JS: Error in syncChain:", error);
3633
3700
  throw error;
@@ -3648,26 +3715,28 @@ class MockWebClient extends WebClient {
3648
3715
  const methodId = MethodName.SYNC_NOTE_TRANSPORT;
3649
3716
 
3650
3717
  try {
3651
- await withSyncLock(dbId, methodId, async () => {
3652
- const wasmWebClient = await this.getWasmWebClient();
3718
+ await withSyncLock(dbId, methodId, async () =>
3719
+ this._serializeWasmCall(async () => {
3720
+ const wasmWebClient = await this.getWasmWebClient();
3653
3721
 
3654
- if (!this.worker) {
3655
- await wasmWebClient.syncNoteTransportImpl();
3656
- return;
3657
- }
3722
+ if (!this.worker) {
3723
+ await wasmWebClient.syncNoteTransportImpl();
3724
+ return;
3725
+ }
3658
3726
 
3659
- const serializedMockChain = (await wasmWebClient.serializeMockChain())
3660
- .buffer;
3661
- const serializedMockNoteTransportNode = (
3662
- await wasmWebClient.serializeMockNoteTransportNode()
3663
- ).buffer;
3727
+ const serializedMockChain = (await wasmWebClient.serializeMockChain())
3728
+ .buffer;
3729
+ const serializedMockNoteTransportNode = (
3730
+ await wasmWebClient.serializeMockNoteTransportNode()
3731
+ ).buffer;
3664
3732
 
3665
- await this.callMethodWithWorker(
3666
- MethodName.SYNC_NOTE_TRANSPORT_MOCK,
3667
- serializedMockChain,
3668
- serializedMockNoteTransportNode
3669
- );
3670
- });
3733
+ await this.callMethodWithWorker(
3734
+ MethodName.SYNC_NOTE_TRANSPORT_MOCK,
3735
+ serializedMockChain,
3736
+ serializedMockNoteTransportNode
3737
+ );
3738
+ })
3739
+ );
3671
3740
  } catch (error) {
3672
3741
  console.error("INDEX.JS: Error in syncNoteTransport:", error);
3673
3742
  throw error;