@miden-sdk/miden-sdk 0.14.0-alpha.2 → 0.14.1

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/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, 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, NoteSyncInfo, NoteTag, NoteType, OutputNote, OutputNoteArray, OutputNoteRecord, OutputNoteState, OutputNotes, OutputNotesArray, Package, PartialNote, ProcedureThreshold, Program, ProvenTransaction, PublicKey, RpcClient, Rpo256, SerializedInputNoteData, SerializedOutputNoteData, SerializedTransactionData, Signature, SigningInputs, SigningInputsType, SlotAndKeys, SparseMerklePath, StorageMap, StorageSlot, StorageSlotArray, SyncSummary, TestUtils, TokenSymbol, TransactionArgs, TransactionFilter, TransactionId, TransactionProver, TransactionRecord, TransactionRequest, TransactionRequestBuilder, TransactionResult, TransactionScript, TransactionScriptInputPair, TransactionScriptInputPairArray, TransactionStatus, TransactionStoreUpdate, TransactionSummary, WebClient, Word, createAuthFalcon512RpoMultisig, initSync, setupLogging } from './Cargo-DlfmzoDc.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';
3
3
 
4
4
  const WorkerAction = Object.freeze({
5
5
  INIT: "init",
@@ -364,22 +364,89 @@ function resolveAuthScheme(scheme, wasm) {
364
364
  }
365
365
 
366
366
  /**
367
- * Resolves a simplified AccountType string to a boolean `mutable` flag
367
+ * Resolves an AccountType value to a boolean `mutable` flag
368
368
  * for the underlying WASM `newWallet()` / `importPublicAccountFromSeed()` calls.
369
369
  *
370
- * @param {string | undefined} accountType - "MutableWallet", "ImmutableWallet", or undefined.
371
- * Defaults to mutable wallet when undefined.
370
+ * Accepts the numeric WASM enum values (2 = immutable, 3 = mutable) or the
371
+ * legacy string aliases ("MutableWallet", "ImmutableWallet"). Defaults to
372
+ * mutable when undefined.
373
+ *
374
+ * @param {number | string | undefined} accountType
372
375
  * @returns {boolean} Whether the account code is mutable.
373
376
  */
374
377
  function resolveAccountMutability(accountType) {
375
- if (accountType == null || accountType === "MutableWallet") {
378
+ if (
379
+ accountType == null ||
380
+ accountType === "MutableWallet" ||
381
+ accountType === 3
382
+ ) {
376
383
  return true;
377
384
  }
378
- if (accountType === "ImmutableWallet") {
385
+ if (accountType === "ImmutableWallet" || accountType === 2) {
379
386
  return false;
380
387
  }
381
388
  throw new Error(
382
- `Unknown wallet account type: "${accountType}". Expected "MutableWallet" or "ImmutableWallet".`
389
+ `Unknown wallet account type: "${accountType}". Expected AccountType.MutableWallet (3) or AccountType.ImmutableWallet (2).`
390
+ );
391
+ }
392
+
393
+ /**
394
+ * Resolves a NoteInput (string | NoteId | InputNoteRecord | Note) to a hex string.
395
+ *
396
+ * - Strings are passed through unchanged.
397
+ * - NoteId WASM objects are converted via `.toString()`.
398
+ * - InputNoteRecord and Note objects (with an `.id()` method) are resolved via `.id().toString()`.
399
+ *
400
+ * @param {string | object} input - The note reference to resolve.
401
+ * @returns {string} The hex note ID string.
402
+ */
403
+ function resolveNoteIdHex(input) {
404
+ if (input == null) {
405
+ throw new Error("Note ID cannot be null or undefined");
406
+ }
407
+ if (typeof input === "string") {
408
+ return input;
409
+ }
410
+ // NoteId WASM object — has toString() but not id() (unlike InputNoteRecord/Note).
411
+ // Check for constructor.fromHex to distinguish from plain objects (which also inherit toString).
412
+ if (
413
+ typeof input.toString === "function" &&
414
+ typeof input.id !== "function" &&
415
+ input.constructor?.fromHex !== undefined
416
+ ) {
417
+ return input.toString();
418
+ }
419
+ // InputNoteRecord, Note, or other object with id() returning NoteId
420
+ if (typeof input.id === "function") {
421
+ return input.id().toString();
422
+ }
423
+ throw new TypeError(
424
+ `Cannot resolve note ID: expected string, NoteId, InputNoteRecord, or Note, got ${typeof input}`
425
+ );
426
+ }
427
+
428
+ /**
429
+ * Resolves a TransactionId reference (string | TransactionId) to a hex string.
430
+ *
431
+ * - Strings are passed through unchanged.
432
+ * - TransactionId WASM objects are converted via `.toHex()`.
433
+ *
434
+ * @param {string | object} input - The transaction ID reference to resolve.
435
+ * @returns {string} The hex transaction ID string.
436
+ */
437
+ function resolveTransactionIdHex(input) {
438
+ if (input == null) {
439
+ throw new Error("Transaction ID cannot be null or undefined");
440
+ }
441
+ if (typeof input === "string") {
442
+ return input;
443
+ }
444
+ // TransactionId WASM object — toHex() returns hex
445
+ if (typeof input.toHex === "function") {
446
+ return input.toHex();
447
+ }
448
+ throw new TypeError(
449
+ `Cannot resolve transaction ID: expected string or TransactionId, got ${typeof input}`
383
450
  );
384
451
  }
385
452
 
@@ -419,25 +486,84 @@ class AccountsResource {
419
486
  this.#client.assertNotTerminated();
420
487
  const wasm = await this.#getWasm();
421
488
 
422
- if (opts?.type === "FungibleFaucet") {
489
+ const type = opts?.type;
490
+
491
+ if (
492
+ type === 0 ||
493
+ type === 1 ||
494
+ type === "FungibleFaucet" ||
495
+ type === "NonFungibleFaucet"
496
+ ) {
423
497
  const storageMode = resolveStorageMode(opts.storage ?? "public", wasm);
424
498
  const authScheme = resolveAuthScheme(opts.auth, wasm);
425
499
  return await this.#inner.newFaucet(
426
500
  storageMode,
427
- false,
501
+ type === 1 || type === "NonFungibleFaucet",
428
502
  opts.symbol,
429
503
  opts.decimals,
430
504
  BigInt(opts.maxSupply),
431
505
  authScheme
432
506
  );
507
+ } else if (
508
+ type === "ImmutableContract" ||
509
+ type === "MutableContract" ||
510
+ opts?.components // Contracts are distinguished from wallets by having components
511
+ ) {
512
+ return await this.#createContract(opts, wasm);
513
+ } else {
514
+ // Default: wallet (mutable or immutable based on type)
515
+ const mutable = resolveAccountMutability(opts?.type);
516
+ const storageMode = resolveStorageMode(opts?.storage ?? "private", wasm);
517
+ const authScheme = resolveAuthScheme(opts?.auth, wasm);
518
+ const seed = opts?.seed ? await hashSeed(opts.seed) : undefined;
519
+ return await this.#inner.newWallet(
520
+ storageMode,
521
+ mutable,
522
+ authScheme,
523
+ seed
524
+ );
433
525
  }
526
+ }
527
+
528
+ async #createContract(opts, wasm) {
529
+ if (!opts.seed)
530
+ throw new Error("Contract creation requires a 'seed' (Uint8Array)");
531
+ if (!opts.auth)
532
+ throw new Error("Contract creation requires an 'auth' (AuthSecretKey)");
533
+
534
+ // Default to immutable when type is omitted (safer for contracts)
535
+ const mutable = opts.type === "MutableContract" || opts.type === 3;
536
+ const accountTypeEnum = mutable
537
+ ? wasm.AccountType.RegularAccountUpdatableCode
538
+ : wasm.AccountType.RegularAccountImmutableCode;
539
+ const storageMode = resolveStorageMode(opts.storage ?? "public", wasm);
540
+ const authComponent =
541
+ wasm.AccountComponent.createAuthComponentFromSecretKey(opts.auth);
542
+
543
+ let builder = new wasm.AccountBuilder(opts.seed)
544
+ .accountType(accountTypeEnum)
545
+ .storageMode(storageMode)
546
+ .withAuthComponent(authComponent);
547
+
548
+ for (const component of opts.components ?? []) {
549
+ builder = builder.withComponent(component);
550
+ }
551
+
552
+ const built = builder.build();
553
+ const account = built.account;
554
+
555
+ await this.#inner.newAccountWithSecretKey(account, opts.auth);
556
+ return account;
557
+ }
558
+
559
+ async insert({ account, overwrite = false }) {
560
+ this.#client.assertNotTerminated();
561
+ await this.#inner.newAccount(account, overwrite);
562
+ }
434
563
 
435
- // Default: wallet (mutable or immutable based on type)
436
- const mutable = resolveAccountMutability(opts?.type);
437
- const storageMode = resolveStorageMode(opts?.storage ?? "private", wasm);
438
- const authScheme = resolveAuthScheme(opts?.auth, wasm);
439
- const seed = opts?.seed ? await hashSeed(opts.seed) : undefined;
440
- return await this.#inner.newWallet(storageMode, mutable, authScheme, seed);
564
+ async getOrImport(ref) {
565
+ this.#client.assertNotTerminated();
566
+ return (await this.get(ref)) ?? (await this.import(ref));
441
567
  }
442
568
 
443
569
  async get(ref) {
@@ -461,7 +587,7 @@ class AccountsResource {
461
587
  if (!account) {
462
588
  throw new Error(`Account not found: ${id.toString()}`);
463
589
  }
464
- const keys = await this.#inner.getPublicKeyCommitmentsOfAccount(id);
590
+ const keys = await this.#inner.keystore.getCommitments(id);
465
591
  return {
466
592
  account,
467
593
  vault: account.vault(),
@@ -484,8 +610,10 @@ class AccountsResource {
484
610
  this.#client.assertNotTerminated();
485
611
  const wasm = await this.#getWasm();
486
612
 
487
- if (typeof input === "string") {
488
- // Import by ID (hex or bech32 string)
613
+ // Early exit for string, Account, and AccountHeader types before property
614
+ // checks, preventing misrouting if a WASM object ever gains a .file or .seed
615
+ // property. Bare AccountId (no .id() method) falls through to the fallback.
616
+ if (typeof input === "string" || typeof input.id === "function") {
489
617
  const id = resolveAccountRef(input, wasm);
490
618
  await this.#inner.importAccountById(id);
491
619
  return await this.#inner.getAccount(id);
@@ -519,9 +647,10 @@ class AccountsResource {
519
647
  );
520
648
  }
521
649
 
522
- throw new Error(
523
- "Invalid import input: expected a string, { file }, or { seed }"
524
- );
650
+ // Fallback: treat as AccountRef (string, AccountId, Account, AccountHeader)
651
+ const id = resolveAccountRef(input, wasm);
652
+ await this.#inner.importAccountById(id);
653
+ return await this.#inner.getAccount(id);
525
654
  }
526
655
 
527
656
  async export(ref) {
@@ -562,9 +691,55 @@ class TransactionsResource {
562
691
  async send(opts) {
563
692
  this.#client.assertNotTerminated();
564
693
  const wasm = await this.#getWasm();
565
- const { accountId, request } = await this.#buildSendRequest(opts, wasm);
566
694
 
567
- const txId = await this.#submitOrSubmitWithProver(
695
+ if (opts.returnNote === true) {
696
+ // returnNote path — build the P2ID note in JS so we can return the Note
697
+ // object to the caller (e.g. for out-of-band delivery to the recipient).
698
+ if (opts.reclaimAfter != null || opts.timelockUntil != null) {
699
+ throw new Error(
700
+ "reclaimAfter and timelockUntil are not supported when returnNote is true"
701
+ );
702
+ }
703
+
704
+ const senderId = resolveAccountRef(opts.account, wasm);
705
+ const receiverId = resolveAccountRef(opts.to, wasm);
706
+ const faucetId = resolveAccountRef(opts.token, wasm);
707
+ const noteType = resolveNoteType(opts.type, wasm);
708
+
709
+ const note = wasm.Note.createP2IDNote(
710
+ senderId,
711
+ receiverId,
712
+ new wasm.NoteAssets([
713
+ new wasm.FungibleAsset(faucetId, BigInt(opts.amount)),
714
+ ]),
715
+ noteType,
716
+ new wasm.NoteAttachment()
717
+ );
718
+
719
+ // NoteArray constructor consumes its elements; use push(&note) to keep
720
+ // `note` valid so we can return it to the caller below.
721
+ const ownOutputs = new wasm.NoteArray();
722
+ ownOutputs.push(note);
723
+ const request = new wasm.TransactionRequestBuilder()
724
+ .withOwnOutputNotes(ownOutputs)
725
+ .build();
726
+
727
+ const { txId, result } = await this.#submitOrSubmitWithProver(
728
+ senderId,
729
+ request,
730
+ opts.prover
731
+ );
732
+
733
+ if (opts.waitForConfirmation) {
734
+ await this.waitFor(txId.toHex(), { timeout: opts.timeout });
735
+ }
736
+
737
+ return { txId, note, result };
738
+ }
739
+
740
+ // Default path — note built in WASM with optional reclaim/timelock
741
+ const { accountId, request } = await this.#buildSendRequest(opts, wasm);
742
+ const { txId, result } = await this.#submitOrSubmitWithProver(
568
743
  accountId,
569
744
  request,
570
745
  opts.prover
@@ -574,7 +749,7 @@ class TransactionsResource {
574
749
  await this.waitFor(txId.toHex(), { timeout: opts.timeout });
575
750
  }
576
751
 
577
- return txId;
752
+ return { txId, note: null, result };
578
753
  }
579
754
 
580
755
  async mint(opts) {
@@ -582,7 +757,7 @@ class TransactionsResource {
582
757
  const wasm = await this.#getWasm();
583
758
  const { accountId, request } = await this.#buildMintRequest(opts, wasm);
584
759
 
585
- const txId = await this.#submitOrSubmitWithProver(
760
+ const { txId, result } = await this.#submitOrSubmitWithProver(
586
761
  accountId,
587
762
  request,
588
763
  opts.prover
@@ -592,7 +767,7 @@ class TransactionsResource {
592
767
  await this.waitFor(txId.toHex(), { timeout: opts.timeout });
593
768
  }
594
769
 
595
- return txId;
770
+ return { txId, result };
596
771
  }
597
772
 
598
773
  async consume(opts) {
@@ -600,7 +775,7 @@ class TransactionsResource {
600
775
  const wasm = await this.#getWasm();
601
776
  const { accountId, request } = await this.#buildConsumeRequest(opts, wasm);
602
777
 
603
- const txId = await this.#submitOrSubmitWithProver(
778
+ const { txId, result } = await this.#submitOrSubmitWithProver(
604
779
  accountId,
605
780
  request,
606
781
  opts.prover
@@ -610,7 +785,7 @@ class TransactionsResource {
610
785
  await this.waitFor(txId.toHex(), { timeout: opts.timeout });
611
786
  }
612
787
 
613
- return txId;
788
+ return { txId, result };
614
789
  }
615
790
 
616
791
  async consumeAll(opts) {
@@ -639,7 +814,7 @@ class TransactionsResource {
639
814
 
640
815
  const request = await this.#inner.newConsumeTransactionRequest(notes);
641
816
 
642
- const txId = await this.#submitOrSubmitWithProver(
817
+ const { txId, result } = await this.#submitOrSubmitWithProver(
643
818
  wasm.AccountId.fromHex(accountIdHex),
644
819
  request,
645
820
  opts.prover
@@ -653,6 +828,7 @@ class TransactionsResource {
653
828
  txId,
654
829
  consumed: toConsume.length,
655
830
  remaining: total - toConsume.length,
831
+ result,
656
832
  };
657
833
  }
658
834
 
@@ -661,7 +837,7 @@ class TransactionsResource {
661
837
  const wasm = await this.#getWasm();
662
838
  const { accountId, request } = await this.#buildSwapRequest(opts, wasm);
663
839
 
664
- const txId = await this.#submitOrSubmitWithProver(
840
+ const { txId, result } = await this.#submitOrSubmitWithProver(
665
841
  accountId,
666
842
  request,
667
843
  opts.prover
@@ -671,7 +847,7 @@ class TransactionsResource {
671
847
  await this.waitFor(txId.toHex(), { timeout: opts.timeout });
672
848
  }
673
849
 
674
- return txId;
850
+ return { txId, result };
675
851
  }
676
852
 
677
853
  async preview(opts) {
@@ -705,6 +881,81 @@ class TransactionsResource {
705
881
  return await this.#inner.executeForSummary(accountId, request);
706
882
  }
707
883
 
884
+ async execute(opts) {
885
+ this.#client.assertNotTerminated();
886
+ const wasm = await this.#getWasm();
887
+ const accountId = resolveAccountRef(opts.account, wasm);
888
+
889
+ let builder = new wasm.TransactionRequestBuilder().withCustomScript(
890
+ opts.script
891
+ );
892
+
893
+ if (opts.foreignAccounts?.length) {
894
+ const accounts = opts.foreignAccounts.map((fa) => {
895
+ // Distinguish { id: AccountRef, storage? } wrapper objects from WASM types
896
+ // (Account/AccountHeader expose .id() as a method, wrappers have .id as a property)
897
+ const isWrapper =
898
+ fa !== null &&
899
+ typeof fa === "object" &&
900
+ "id" in fa &&
901
+ typeof fa.id !== "function";
902
+ const id = resolveAccountRef(isWrapper ? fa.id : fa, wasm);
903
+ const storage =
904
+ isWrapper && fa.storage
905
+ ? fa.storage
906
+ : new wasm.AccountStorageRequirements();
907
+ return wasm.ForeignAccount.public(id, storage);
908
+ });
909
+ builder = builder.withForeignAccounts(
910
+ new wasm.ForeignAccountArray(accounts)
911
+ );
912
+ }
913
+
914
+ const request = builder.build();
915
+ const { txId, result } = await this.#submitOrSubmitWithProver(
916
+ accountId,
917
+ request,
918
+ opts.prover
919
+ );
920
+
921
+ if (opts.waitForConfirmation) {
922
+ await this.waitFor(txId.toHex(), { timeout: opts.timeout });
923
+ }
924
+
925
+ return { txId, result };
926
+ }
927
+
928
+ async executeProgram(opts) {
929
+ this.#client.assertNotTerminated();
930
+ const wasm = await this.#getWasm();
931
+ const accountId = resolveAccountRef(opts.account, wasm);
932
+
933
+ let foreignAccountsArray = new wasm.ForeignAccountArray();
934
+ if (opts.foreignAccounts?.length) {
935
+ const accounts = opts.foreignAccounts.map((fa) => {
936
+ const isWrapper =
937
+ fa !== null &&
938
+ typeof fa === "object" &&
939
+ "id" in fa &&
940
+ typeof fa.id !== "function";
941
+ const id = resolveAccountRef(isWrapper ? fa.id : fa, wasm);
942
+ const storage =
943
+ isWrapper && fa.storage
944
+ ? fa.storage
945
+ : new wasm.AccountStorageRequirements();
946
+ return wasm.ForeignAccount.public(id, storage);
947
+ });
948
+ foreignAccountsArray = new wasm.ForeignAccountArray(accounts);
949
+ }
950
+
951
+ return await this.#inner.executeProgram(
952
+ accountId,
953
+ opts.script,
954
+ opts.adviceInputs ?? new wasm.AdviceInputs(),
955
+ foreignAccountsArray
956
+ );
957
+ }
958
+
708
959
  async submit(account, request, opts) {
709
960
  this.#client.assertNotTerminated();
710
961
  const wasm = await this.#getWasm();
@@ -726,7 +977,9 @@ class TransactionsResource {
726
977
  } else if (query.status === "uncommitted") {
727
978
  filter = wasm.TransactionFilter.uncommitted();
728
979
  } else if (query.ids) {
729
- const txIds = query.ids.map((id) => wasm.TransactionId.fromHex(id));
980
+ const txIds = query.ids.map((id) =>
981
+ wasm.TransactionId.fromHex(resolveTransactionIdHex(id))
982
+ );
730
983
  filter = wasm.TransactionFilter.ids(txIds);
731
984
  } else if (query.expiredBefore !== undefined) {
732
985
  filter = wasm.TransactionFilter.expiredBefore(query.expiredBefore);
@@ -740,7 +993,7 @@ class TransactionsResource {
740
993
  /**
741
994
  * Polls for transaction confirmation.
742
995
  *
743
- * @param {string} txId - Transaction ID hex string.
996
+ * @param {string | TransactionId} txId - Transaction ID hex string or TransactionId object.
744
997
  * @param {WaitOptions} [opts] - Polling options.
745
998
  * @param {number} [opts.timeout=60000] - Wall-clock polling timeout in
746
999
  * milliseconds. This is NOT a block height — it controls how long the
@@ -752,6 +1005,7 @@ class TransactionsResource {
752
1005
  */
753
1006
  async waitFor(txId, opts) {
754
1007
  this.#client.assertNotTerminated();
1008
+ const hex = resolveTransactionIdHex(txId);
755
1009
  const timeout = opts?.timeout ?? 60_000;
756
1010
  const interval = opts?.interval ?? 5_000;
757
1011
  const start = Date.now();
@@ -774,7 +1028,7 @@ class TransactionsResource {
774
1028
 
775
1029
  // Recreate filter each iteration — WASM consumes it by value
776
1030
  const filter = wasm.TransactionFilter.ids([
777
- wasm.TransactionId.fromHex(txId),
1031
+ wasm.TransactionId.fromHex(hex),
778
1032
  ]);
779
1033
  const txs = await this.#inner.getTransactions(filter);
780
1034
 
@@ -788,7 +1042,7 @@ class TransactionsResource {
788
1042
  return;
789
1043
  }
790
1044
  if (status.isDiscarded()) {
791
- throw new Error(`Transaction rejected: ${txId}`);
1045
+ throw new Error(`Transaction rejected: ${hex}`);
792
1046
  }
793
1047
  }
794
1048
 
@@ -841,6 +1095,37 @@ class TransactionsResource {
841
1095
  async #buildConsumeRequest(opts, wasm) {
842
1096
  const accountId = resolveAccountRef(opts.account, wasm);
843
1097
  const noteInputs = Array.isArray(opts.notes) ? opts.notes : [opts.notes];
1098
+
1099
+ const isDirectNote = (input) =>
1100
+ input !== null &&
1101
+ typeof input === "object" &&
1102
+ typeof input.id === "function" &&
1103
+ typeof input.toNote !== "function";
1104
+
1105
+ const hasDirectNotes = noteInputs.some(isDirectNote);
1106
+
1107
+ if (hasDirectNotes) {
1108
+ // At least one raw Note object — use NoteAndArgs builder path
1109
+ // (the only WASM path that accepts unauthenticated notes not in the store).
1110
+ const resolvedNotes = await Promise.all(
1111
+ noteInputs.map(async (input) => {
1112
+ if (isDirectNote(input)) return input;
1113
+ if (input && typeof input.toNote === "function")
1114
+ return input.toNote();
1115
+ return await this.#resolveNoteInput(input);
1116
+ })
1117
+ );
1118
+
1119
+ const noteAndArgsArr = resolvedNotes.map(
1120
+ (note) => new wasm.NoteAndArgs(note, null)
1121
+ );
1122
+ const request = new wasm.TransactionRequestBuilder()
1123
+ .withInputNotes(new wasm.NoteAndArgsArray(noteAndArgsArr))
1124
+ .build();
1125
+ return { accountId, request };
1126
+ }
1127
+
1128
+ // Standard path: all inputs are IDs or records — look up from store.
844
1129
  const notes = await Promise.all(
845
1130
  noteInputs.map((input) => this.#resolveNoteInput(input))
846
1131
  );
@@ -882,8 +1167,15 @@ class TransactionsResource {
882
1167
  if (input && typeof input.toNote === "function") {
883
1168
  return input.toNote();
884
1169
  }
885
- // NoteId — look up the note by its hex ID
886
- if (input && input.constructor?.name === "NoteId") {
1170
+ // NoteId — has toString() but not toNote() or id() (unlike InputNoteRecord/Note).
1171
+ // Check for constructor.fromHex to distinguish from plain objects.
1172
+ if (
1173
+ input &&
1174
+ typeof input.toString === "function" &&
1175
+ typeof input.toNote !== "function" &&
1176
+ typeof input.id !== "function" &&
1177
+ input.constructor?.fromHex !== undefined
1178
+ ) {
887
1179
  const hex = input.toString();
888
1180
  const record = await this.#inner.getInputNote(hex);
889
1181
  if (!record) {
@@ -896,15 +1188,15 @@ class TransactionsResource {
896
1188
  }
897
1189
 
898
1190
  async #submitOrSubmitWithProver(accountId, request, perCallProver) {
1191
+ const result = await this.#inner.executeTransaction(accountId, request);
899
1192
  const prover = perCallProver ?? this.#client.defaultProver;
900
- if (prover) {
901
- return await this.#inner.submitNewTransactionWithProver(
902
- accountId,
903
- request,
904
- prover
905
- );
906
- }
907
- return await this.#inner.submitNewTransaction(accountId, request);
1193
+ const proven = prover
1194
+ ? await this.#inner.proveTransaction(result, prover)
1195
+ : await this.#inner.proveTransaction(result);
1196
+ const txId = result.id();
1197
+ const height = await this.#inner.submitProvenTransaction(proven, result);
1198
+ await this.#inner.applyTransaction(result, height);
1199
+ return { txId, result };
908
1200
  }
909
1201
  }
910
1202
 
@@ -928,7 +1220,7 @@ class NotesResource {
928
1220
 
929
1221
  async get(noteId) {
930
1222
  this.#client.assertNotTerminated();
931
- const result = await this.#inner.getInputNote(noteId);
1223
+ const result = await this.#inner.getInputNote(resolveNoteIdHex(noteId));
932
1224
  return result ?? null;
933
1225
  }
934
1226
 
@@ -943,7 +1235,8 @@ class NotesResource {
943
1235
  this.#client.assertNotTerminated();
944
1236
  const wasm = await this.#getWasm();
945
1237
  const accountId = resolveAccountRef(opts.account, wasm);
946
- return await this.#inner.getConsumableNotes(accountId);
1238
+ const consumable = await this.#inner.getConsumableNotes(accountId);
1239
+ return consumable.map((c) => c.inputNoteRecord());
947
1240
  }
948
1241
 
949
1242
  async import(noteFile) {
@@ -955,7 +1248,7 @@ class NotesResource {
955
1248
  this.#client.assertNotTerminated();
956
1249
  const wasm = await this.#getWasm();
957
1250
  const format = opts?.format ?? wasm.NoteExportFormat.Full;
958
- return await this.#inner.exportNoteFile(noteId, format);
1251
+ return await this.#inner.exportNoteFile(resolveNoteIdHex(noteId), format);
959
1252
  }
960
1253
 
961
1254
  async fetchPrivate(opts) {
@@ -970,11 +1263,27 @@ class NotesResource {
970
1263
  async sendPrivate(opts) {
971
1264
  this.#client.assertNotTerminated();
972
1265
  const wasm = await this.#getWasm();
973
- const noteRecord = await this.#inner.getInputNote(opts.noteId);
974
- if (!noteRecord) {
975
- throw new Error(`Note not found: ${opts.noteId}`);
1266
+
1267
+ let note;
1268
+ const input = opts.note;
1269
+ // Check if input is a Note object (has .id() and .assets() but not .toNote())
1270
+ if (
1271
+ input &&
1272
+ typeof input === "object" &&
1273
+ typeof input.id === "function" &&
1274
+ typeof input.assets === "function" &&
1275
+ typeof input.toNote !== "function"
1276
+ ) {
1277
+ note = input;
1278
+ } else {
1279
+ const noteHex = resolveNoteIdHex(input);
1280
+ const noteRecord = await this.#inner.getInputNote(noteHex);
1281
+ if (!noteRecord) {
1282
+ throw new Error(`Note not found: ${noteHex}`);
1283
+ }
1284
+ note = noteRecord.toNote();
976
1285
  }
977
- const note = noteRecord.toNote();
1286
+
978
1287
  const address = resolveAddress(opts.to, wasm);
979
1288
  await this.#inner.sendPrivateNote(note, address);
980
1289
  }
@@ -986,7 +1295,9 @@ function buildNoteFilter(query, wasm) {
986
1295
  }
987
1296
 
988
1297
  if (query.ids) {
989
- const noteIds = query.ids.map((id) => wasm.NoteId.fromHex(id));
1298
+ const noteIds = query.ids.map((id) =>
1299
+ wasm.NoteId.fromHex(resolveNoteIdHex(id))
1300
+ );
990
1301
  return new wasm.NoteFilter(wasm.NoteFilterTypes.List, noteIds);
991
1302
  }
992
1303
 
@@ -1071,6 +1382,102 @@ class SettingsResource {
1071
1382
  }
1072
1383
  }
1073
1384
 
1385
+ class CompilerResource {
1386
+ #inner;
1387
+ #getWasm;
1388
+ #client;
1389
+
1390
+ constructor(inner, getWasm, client) {
1391
+ this.#inner = inner;
1392
+ this.#getWasm = getWasm;
1393
+ this.#client = client;
1394
+ }
1395
+
1396
+ /**
1397
+ * Compiles MASM code + slots into an AccountComponent ready for accounts.create().
1398
+ *
1399
+ * @param {{ code: string, slots: StorageSlot[], supportAllTypes?: boolean }} opts
1400
+ * @returns {Promise<AccountComponent>}
1401
+ */
1402
+ async component({ code, slots = [], supportAllTypes = true }) {
1403
+ this.#client.assertNotTerminated();
1404
+ const wasm = await this.#getWasm();
1405
+ const builder = this.#inner.createCodeBuilder();
1406
+ const compiled = builder.compileAccountComponentCode(code);
1407
+ const component = wasm.AccountComponent.compile(compiled, slots);
1408
+ return supportAllTypes ? component.withSupportsAllTypes() : component;
1409
+ }
1410
+
1411
+ /**
1412
+ * Compiles a transaction script, optionally linking named libraries inline.
1413
+ *
1414
+ * @param {{ code: string, libraries?: Array<{ namespace: string, code: string, linking?: "dynamic" | "static" }> }} opts
1415
+ * @returns {Promise<TransactionScript>}
1416
+ */
1417
+ async txScript({ code, libraries = [] }) {
1418
+ this.#client.assertNotTerminated();
1419
+ // Ensure WASM is initialized (result unused — only #inner needs it)
1420
+ await this.#getWasm();
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
+ }
1432
+ } else {
1433
+ // Pre-built library object — link dynamically
1434
+ builder.linkDynamicLibrary(lib);
1435
+ }
1436
+ }
1437
+ return builder.compileTxScript(code);
1438
+ }
1439
+ }
1440
+
1441
+ class KeystoreResource {
1442
+ #inner;
1443
+ #client;
1444
+
1445
+ constructor(inner, client) {
1446
+ this.#inner = inner;
1447
+ this.#client = client;
1448
+ }
1449
+
1450
+ async insert(accountId, secretKey) {
1451
+ this.#client.assertNotTerminated();
1452
+ const ks = this.#inner.keystore;
1453
+ return await ks.insert(accountId, secretKey);
1454
+ }
1455
+
1456
+ async get(pubKeyCommitment) {
1457
+ this.#client.assertNotTerminated();
1458
+ const ks = this.#inner.keystore;
1459
+ return await ks.get(pubKeyCommitment);
1460
+ }
1461
+
1462
+ async remove(pubKeyCommitment) {
1463
+ this.#client.assertNotTerminated();
1464
+ const ks = this.#inner.keystore;
1465
+ return await ks.remove(pubKeyCommitment);
1466
+ }
1467
+
1468
+ async getCommitments(accountId) {
1469
+ this.#client.assertNotTerminated();
1470
+ const ks = this.#inner.keystore;
1471
+ return await ks.getCommitments(accountId);
1472
+ }
1473
+
1474
+ async getAccountId(pubKeyCommitment) {
1475
+ this.#client.assertNotTerminated();
1476
+ const ks = this.#inner.keystore;
1477
+ return await ks.getAccountId(pubKeyCommitment);
1478
+ }
1479
+ }
1480
+
1074
1481
  /**
1075
1482
  * MidenClient wraps the existing proxy-wrapped WebClient with a resource-based API.
1076
1483
  *
@@ -1099,15 +1506,24 @@ class MidenClient {
1099
1506
  this.notes = new NotesResource(inner, getWasm, this);
1100
1507
  this.tags = new TagsResource(inner, getWasm, this);
1101
1508
  this.settings = new SettingsResource(inner, getWasm, this);
1509
+ this.compile = new CompilerResource(inner, getWasm, this);
1510
+ this.keystore = new KeystoreResource(inner, this);
1102
1511
  }
1103
1512
 
1104
1513
  /**
1105
1514
  * Creates and initializes a new MidenClient.
1106
1515
  *
1516
+ * If no `rpcUrl` is provided, defaults to testnet with full configuration
1517
+ * (RPC, prover, note transport, autoSync).
1518
+ *
1107
1519
  * @param {ClientOptions} [options] - Client configuration options.
1108
1520
  * @returns {Promise<MidenClient>} A fully initialized client.
1109
1521
  */
1110
1522
  static async create(options) {
1523
+ if (!options?.rpcUrl) {
1524
+ return MidenClient.createTestnet(options);
1525
+ }
1526
+
1111
1527
  const getWasm = MidenClient._getWasmOrThrow;
1112
1528
  const WebClientClass = MidenClient._WasmWebClient;
1113
1529
 
@@ -1119,11 +1535,14 @@ class MidenClient {
1119
1535
 
1120
1536
  const seed = options?.seed ? await hashSeed(options.seed) : undefined;
1121
1537
 
1538
+ const rpcUrl = resolveRpcUrl(options?.rpcUrl);
1539
+ const noteTransportUrl = resolveNoteTransportUrl(options?.noteTransportUrl);
1540
+
1122
1541
  let inner;
1123
1542
  if (options?.keystore) {
1124
1543
  inner = await WebClientClass.createClientWithExternalKeystore(
1125
- options?.rpcUrl,
1126
- options?.noteTransportUrl,
1544
+ rpcUrl,
1545
+ noteTransportUrl,
1127
1546
  seed,
1128
1547
  options?.storeName,
1129
1548
  options.keystore.getKey,
@@ -1132,8 +1551,8 @@ class MidenClient {
1132
1551
  );
1133
1552
  } else {
1134
1553
  inner = await WebClientClass.createClient(
1135
- options?.rpcUrl,
1136
- options?.noteTransportUrl,
1554
+ rpcUrl,
1555
+ noteTransportUrl,
1137
1556
  seed,
1138
1557
  options?.storeName
1139
1558
  );
@@ -1142,10 +1561,7 @@ class MidenClient {
1142
1561
  let defaultProver = null;
1143
1562
  if (options?.proverUrl) {
1144
1563
  const wasm = await getWasm();
1145
- defaultProver = wasm.TransactionProver.newRemoteProver(
1146
- options.proverUrl,
1147
- undefined
1148
- );
1564
+ defaultProver = resolveProver(options.proverUrl, wasm);
1149
1565
  }
1150
1566
 
1151
1567
  const client = new MidenClient(inner, getWasm, defaultProver);
@@ -1159,15 +1575,39 @@ class MidenClient {
1159
1575
 
1160
1576
  /**
1161
1577
  * Creates a client preconfigured for testnet use.
1162
- * Defaults to autoSync: true.
1163
1578
  *
1164
- * @param {object} [options] - Options (autoSync can be overridden).
1579
+ * Defaults: rpcUrl "testnet", proverUrl "testnet", noteTransportUrl "testnet", autoSync true.
1580
+ * All defaults can be overridden via options.
1581
+ *
1582
+ * @param {ClientOptions} [options] - Options to override defaults.
1165
1583
  * @returns {Promise<MidenClient>} A fully initialized testnet client.
1166
1584
  */
1167
1585
  static async createTestnet(options) {
1168
1586
  return MidenClient.create({
1587
+ rpcUrl: "testnet",
1588
+ proverUrl: "testnet",
1589
+ noteTransportUrl: "testnet",
1590
+ autoSync: true,
1591
+ ...options,
1592
+ });
1593
+ }
1594
+
1595
+ /**
1596
+ * Creates a client preconfigured for devnet use.
1597
+ *
1598
+ * Defaults: rpcUrl "devnet", proverUrl "devnet", noteTransportUrl "devnet", autoSync true.
1599
+ * All defaults can be overridden via options.
1600
+ *
1601
+ * @param {ClientOptions} [options] - Options to override defaults.
1602
+ * @returns {Promise<MidenClient>} A fully initialized devnet client.
1603
+ */
1604
+ static async createDevnet(options) {
1605
+ return MidenClient.create({
1606
+ rpcUrl: "devnet",
1607
+ proverUrl: "devnet",
1608
+ noteTransportUrl: "devnet",
1609
+ autoSync: true,
1169
1610
  ...options,
1170
- autoSync: options?.autoSync ?? true,
1171
1611
  });
1172
1612
  }
1173
1613
 
@@ -1244,30 +1684,13 @@ class MidenClient {
1244
1684
  }
1245
1685
 
1246
1686
  /**
1247
- * Exports the client store as a versioned snapshot.
1687
+ * Returns the identifier of the underlying store (e.g. IndexedDB database name, file path).
1248
1688
  *
1249
- * @returns {Promise<StoreSnapshot>} The store snapshot.
1689
+ * @returns {string} The store identifier.
1250
1690
  */
1251
- async exportStore() {
1691
+ storeIdentifier() {
1252
1692
  this.assertNotTerminated();
1253
- const data = await this.#inner.exportStore();
1254
- return { version: 1, data };
1255
- }
1256
-
1257
- /**
1258
- * Imports a previously exported store snapshot.
1259
- *
1260
- * @param {StoreSnapshot} snapshot - The store snapshot to import.
1261
- */
1262
- async importStore(snapshot) {
1263
- this.assertNotTerminated();
1264
- if (!snapshot || snapshot.version !== 1) {
1265
- throw new Error(
1266
- `Unsupported store snapshot version: ${snapshot?.version}. Expected version 1.`
1267
- );
1268
- }
1269
- // Second arg is the store password (empty string = no encryption)
1270
- await this.#inner.forceImportStore(snapshot.data, "");
1693
+ return this.#inner.storeIdentifier();
1271
1694
  }
1272
1695
 
1273
1696
  // ── Mock-only methods ──
@@ -1314,6 +1737,64 @@ class MidenClient {
1314
1737
  }
1315
1738
  }
1316
1739
 
1740
+ const RPC_URLS = {
1741
+ testnet: "https://rpc.testnet.miden.io",
1742
+ devnet: "https://rpc.devnet.miden.io",
1743
+ localhost: "http://localhost:57291",
1744
+ local: "http://localhost:57291",
1745
+ };
1746
+
1747
+ /**
1748
+ * Resolves an rpcUrl shorthand or raw URL into a concrete endpoint string.
1749
+ *
1750
+ * @param {string | undefined} rpcUrl - "testnet", "devnet", "localhost", "local", or a raw URL.
1751
+ * @returns {string | undefined} A fully qualified URL, or undefined to use the SDK default.
1752
+ */
1753
+ function resolveRpcUrl(rpcUrl) {
1754
+ if (!rpcUrl) return undefined;
1755
+ return RPC_URLS[rpcUrl.trim().toLowerCase()] ?? rpcUrl;
1756
+ }
1757
+
1758
+ const PROVER_URLS = {
1759
+ devnet: "https://tx-prover.devnet.miden.io",
1760
+ testnet: "https://tx-prover.testnet.miden.io",
1761
+ };
1762
+
1763
+ const NOTE_TRANSPORT_URLS = {
1764
+ testnet: "https://transport.miden.io",
1765
+ devnet: "https://transport.devnet.miden.io",
1766
+ };
1767
+
1768
+ /**
1769
+ * Resolves a noteTransportUrl shorthand or raw URL into a concrete endpoint string.
1770
+ *
1771
+ * @param {string | undefined} noteTransportUrl - "testnet", "devnet", or a raw URL.
1772
+ * @returns {string | undefined} A fully qualified URL, or undefined if omitted.
1773
+ */
1774
+ function resolveNoteTransportUrl(noteTransportUrl) {
1775
+ if (!noteTransportUrl) return undefined;
1776
+ return (
1777
+ NOTE_TRANSPORT_URLS[noteTransportUrl.trim().toLowerCase()] ??
1778
+ noteTransportUrl
1779
+ );
1780
+ }
1781
+
1782
+ /**
1783
+ * Resolves a proverUrl shorthand or raw URL into a TransactionProver.
1784
+ *
1785
+ * @param {string} proverUrl - "local", "devnet", "testnet", or a raw URL.
1786
+ * @param {object} wasm - Loaded WASM module.
1787
+ * @returns {object} A TransactionProver instance.
1788
+ */
1789
+ function resolveProver(proverUrl, wasm) {
1790
+ const normalized = proverUrl.trim().toLowerCase();
1791
+ if (normalized === "local") {
1792
+ return wasm.TransactionProver.newLocalProver();
1793
+ }
1794
+ const remoteUrl = PROVER_URLS[normalized] ?? proverUrl;
1795
+ return wasm.TransactionProver.newRemoteProver(remoteUrl, undefined);
1796
+ }
1797
+
1317
1798
  // Module-level WASM reference, set by index.js after initialization
1318
1799
  let _wasm = null;
1319
1800
  let _WebClient = null;
@@ -1339,7 +1820,7 @@ function getWasm() {
1339
1820
  * Creates a P2ID (Pay-to-ID) note.
1340
1821
  *
1341
1822
  * @param {NoteOptions} opts - Note creation options.
1342
- * @returns {OutputNote} The created output note.
1823
+ * @returns {Note} The created note.
1343
1824
  */
1344
1825
  function createP2IDNote(opts) {
1345
1826
  const wasm = getWasm();
@@ -1351,21 +1832,20 @@ function createP2IDNote(opts) {
1351
1832
  ? new wasm.NoteAttachment(opts.attachment)
1352
1833
  : new wasm.NoteAttachment([]);
1353
1834
 
1354
- const note = wasm.Note.createP2IDNote(
1835
+ return wasm.Note.createP2IDNote(
1355
1836
  sender,
1356
1837
  target,
1357
1838
  noteAssets,
1358
1839
  noteType,
1359
1840
  attachment
1360
1841
  );
1361
- return wasm.OutputNote.full(note);
1362
1842
  }
1363
1843
 
1364
1844
  /**
1365
1845
  * Creates a P2IDE (Pay-to-ID with Expiration) note.
1366
1846
  *
1367
1847
  * @param {P2IDEOptions} opts - Note creation options with timelock/reclaim.
1368
- * @returns {OutputNote} The created output note.
1848
+ * @returns {Note} The created note.
1369
1849
  */
1370
1850
  function createP2IDENote(opts) {
1371
1851
  const wasm = getWasm();
@@ -1377,7 +1857,7 @@ function createP2IDENote(opts) {
1377
1857
  ? new wasm.NoteAttachment(opts.attachment)
1378
1858
  : new wasm.NoteAttachment([]);
1379
1859
 
1380
- const note = wasm.Note.createP2IDENote(
1860
+ return wasm.Note.createP2IDENote(
1381
1861
  sender,
1382
1862
  target,
1383
1863
  noteAssets,
@@ -1386,7 +1866,6 @@ function createP2IDENote(opts) {
1386
1866
  noteType,
1387
1867
  attachment
1388
1868
  );
1389
- return wasm.OutputNote.full(note);
1390
1869
  }
1391
1870
 
1392
1871
  /**
@@ -1425,9 +1904,16 @@ function buildNoteAssets(assets, wasm) {
1425
1904
  }
1426
1905
 
1427
1906
  const AccountType = Object.freeze({
1428
- MutableWallet: "MutableWallet",
1429
- ImmutableWallet: "ImmutableWallet",
1430
- FungibleFaucet: "FungibleFaucet",
1907
+ // WASM-compatible numeric values — usable with AccountBuilder directly
1908
+ FungibleFaucet: 0,
1909
+ NonFungibleFaucet: 1,
1910
+ RegularAccountImmutableCode: 2,
1911
+ RegularAccountUpdatableCode: 3,
1912
+ // SDK-friendly aliases (same numeric values as their WASM equivalents)
1913
+ MutableWallet: 3,
1914
+ ImmutableWallet: 2,
1915
+ ImmutableContract: 2,
1916
+ MutableContract: 3,
1431
1917
  });
1432
1918
 
1433
1919
  const AuthScheme = Object.freeze({
@@ -1435,6 +1921,19 @@ const AuthScheme = Object.freeze({
1435
1921
  ECDSA: "ecdsa",
1436
1922
  });
1437
1923
 
1924
+ const NoteVisibility = Object.freeze({
1925
+ Public: "public",
1926
+ Private: "private",
1927
+ });
1928
+
1929
+ const StorageMode = Object.freeze({
1930
+ Public: "public",
1931
+ Private: "private",
1932
+ Network: "network",
1933
+ });
1934
+
1935
+ const MOCK_STORE_NAME = "mock_client_db";
1936
+
1438
1937
  const buildTypedArraysExport = (exportObject) => {
1439
1938
  return Object.entries(exportObject).reduce(
1440
1939
  (exports$1, [exportName, _export]) => {
@@ -1600,9 +2099,11 @@ class WebClient {
1600
2099
  if (typeof Worker !== "undefined") {
1601
2100
  console.log("WebClient: Web Workers are available.");
1602
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.
1603
2105
  this.worker = new Worker(
1604
- new URL("./workers/web-client-methods-worker.js", import.meta.url),
1605
- { type: "module" }
2106
+ new URL("./workers/web-client-methods-worker.js", import.meta.url)
1606
2107
  );
1607
2108
 
1608
2109
  // Map to track pending worker requests.
@@ -1908,6 +2409,20 @@ class WebClient {
1908
2409
  });
1909
2410
  }
1910
2411
 
2412
+ async newAccount(account, overwrite) {
2413
+ return this._serializeWasmCall(async () => {
2414
+ const wasmWebClient = await this.getWasmWebClient();
2415
+ return await wasmWebClient.newAccount(account, overwrite);
2416
+ });
2417
+ }
2418
+
2419
+ async newAccountWithSecretKey(account, secretKey) {
2420
+ return this._serializeWasmCall(async () => {
2421
+ const wasmWebClient = await this.getWasmWebClient();
2422
+ return await wasmWebClient.newAccountWithSecretKey(account, secretKey);
2423
+ });
2424
+ }
2425
+
1911
2426
  async submitNewTransaction(accountId, transactionRequest) {
1912
2427
  try {
1913
2428
  if (!this.worker) {
@@ -2136,7 +2651,16 @@ class WebClient {
2136
2651
 
2137
2652
  class MockWebClient extends WebClient {
2138
2653
  constructor(seed, logLevel) {
2139
- super(null, null, seed, "mock", undefined, undefined, undefined, logLevel);
2654
+ super(
2655
+ null,
2656
+ null,
2657
+ seed,
2658
+ MOCK_STORE_NAME,
2659
+ undefined,
2660
+ undefined,
2661
+ undefined,
2662
+ logLevel
2663
+ );
2140
2664
  }
2141
2665
 
2142
2666
  initializeWorker() {
@@ -2377,5 +2901,5 @@ MidenClient._MockWasmWebClient = MockWebClient;
2377
2901
  MidenClient._getWasmOrThrow = getWasmOrThrow;
2378
2902
  _setWebClient(WebClient);
2379
2903
 
2380
- export { AccountType, AuthScheme, MidenArrays, MidenClient, MockWebClient as MockWasmWebClient, WebClient as WasmWebClient, buildSwapTag, createP2IDENote, createP2IDNote, getWasmOrThrow };
2904
+ export { AccountType, AuthScheme, MidenArrays, MidenClient, MockWebClient as MockWasmWebClient, NoteVisibility, StorageMode, WebClient as WasmWebClient, buildSwapTag, createP2IDENote, createP2IDNote, getWasmOrThrow };
2381
2905
  //# sourceMappingURL=index.js.map