@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/README.md +2 -2
- package/dist/{Cargo-DlfmzoDc.js → Cargo-BZOulF0S.js} +1713 -799
- package/dist/Cargo-BZOulF0S.js.map +1 -0
- package/dist/api-types.d.ts +461 -53
- package/dist/assets/miden_client_web.wasm +0 -0
- package/dist/crates/miden_client_web.d.ts +351 -107
- package/dist/docs-entry.d.ts +1 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +622 -98
- package/dist/index.js.map +1 -1
- package/dist/wasm.js +11 -1
- package/dist/wasm.js.map +1 -1
- package/dist/workers/assets/miden_client_web.wasm +0 -0
- package/dist/workers/web-client-methods-worker.js +24622 -4
- package/dist/workers/web-client-methods-worker.js.map +1 -1
- package/package.json +9 -4
- package/dist/Cargo-DlfmzoDc.js.map +0 -1
- package/dist/workers/Cargo-DlfmzoDc-DlfmzoDc.js +0 -23537
- package/dist/workers/Cargo-DlfmzoDc-DlfmzoDc.js.map +0 -1
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,
|
|
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
|
|
367
|
+
* Resolves an AccountType value to a boolean `mutable` flag
|
|
368
368
|
* for the underlying WASM `newWallet()` / `importPublicAccountFromSeed()` calls.
|
|
369
369
|
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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.
|
|
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
|
-
|
|
488
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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
|
-
|
|
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(¬e) 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) =>
|
|
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(
|
|
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: ${
|
|
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 —
|
|
886
|
-
|
|
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
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
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
|
-
|
|
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
|
-
|
|
974
|
-
|
|
975
|
-
|
|
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
|
-
|
|
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) =>
|
|
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
|
-
|
|
1126
|
-
|
|
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
|
-
|
|
1136
|
-
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
1687
|
+
* Returns the identifier of the underlying store (e.g. IndexedDB database name, file path).
|
|
1248
1688
|
*
|
|
1249
|
-
* @returns {
|
|
1689
|
+
* @returns {string} The store identifier.
|
|
1250
1690
|
*/
|
|
1251
|
-
|
|
1691
|
+
storeIdentifier() {
|
|
1252
1692
|
this.assertNotTerminated();
|
|
1253
|
-
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
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(
|
|
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
|