@miden-sdk/react 0.13.2 → 0.14.0-alpha

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/CLAUDE.md CHANGED
@@ -332,6 +332,34 @@ import { SignerContext } from "@miden-sdk/react";
332
332
  </SignerContext.Provider>
333
333
  ```
334
334
 
335
+ ### Custom Account Components
336
+
337
+ Signer providers can attach custom `AccountComponent` instances to accounts
338
+ via the `customComponents` field on `SignerAccountConfig`. This is useful for
339
+ including application-specific logic compiled from `.masp` packages (e.g. a
340
+ DEX component or custom smart contract) alongside the default auth and basic
341
+ wallet components.
342
+
343
+ ```tsx
344
+ import { SignerContext, type SignerAccountConfig } from "@miden-sdk/react";
345
+ import { AccountComponent } from "@miden-sdk/miden-sdk";
346
+
347
+ // Load a compiled .masp component (e.g. from your build pipeline)
348
+ const myDexComponent: AccountComponent = await loadCompiledComponent();
349
+
350
+ const accountConfig: SignerAccountConfig = {
351
+ publicKeyCommitment: userPublicKeyCommitment,
352
+ accountType: "RegularAccountUpdatableCode",
353
+ storageMode: myStorageMode,
354
+ customComponents: [myDexComponent],
355
+ };
356
+ ```
357
+
358
+ Components are appended to the `AccountBuilder` after the default basic wallet
359
+ component and before `build()` is called, so the account always includes wallet
360
+ functionality plus any extras you provide. The field is optional — omitting it
361
+ or passing an empty array preserves the default behavior.
362
+
335
363
  ## Account ID Formats
336
364
 
337
365
  Both formats work interchangeably in all hooks:
package/README.md CHANGED
@@ -9,6 +9,12 @@ React hooks library for the Miden Web Client. Provides a simple, ergonomic inter
9
9
  - **Auto-Sync** - Automatic background synchronization with the network
10
10
  - **TypeScript First** - Full type safety with comprehensive type exports
11
11
  - **Consistent Patterns** - All hooks follow predictable patterns for loading, errors, and state
12
+ - **Note Attachments** - Send and read arbitrary data payloads on notes via `useSend()` and `readNoteAttachment()`
13
+ - **Temporal Note Tracking** - `useNoteStream()` tracks when notes first appear, with built-in filtering, handled-note exclusion, and phase snapshots
14
+ - **Session Wallets** - `useSessionAccount()` manages the create-fund-consume lifecycle for temporary wallets
15
+ - **Concurrency Safety** - Transaction hooks prevent double-sends with built-in concurrency guards
16
+ - **Auto Pre-Sync** - Transaction hooks sync before executing by default (opt out with `skipSync`)
17
+ - **WASM Error Wrapping** - Cryptic WASM errors are intercepted and replaced with actionable messages
12
18
 
13
19
  ## Installation
14
20
 
@@ -438,6 +444,8 @@ function NotesList() {
438
444
  const { notes: committedNotes } = useNotes({
439
445
  status: 'committed', // 'all' | 'consumed' | 'committed' | 'expected' | 'processing'
440
446
  accountId: '0x...', // Filter by account
447
+ sender: '0x...', // Filter by sender (any format, normalized internally)
448
+ excludeIds: ['0xnote1...'], // Exclude specific note IDs
441
449
  });
442
450
 
443
451
  return (
@@ -460,6 +468,61 @@ function NotesList() {
460
468
  }
461
469
  ```
462
470
 
471
+ #### `useNoteStream(options?)`
472
+
473
+ Temporal note tracking with a unified model. Replaces the common pattern of
474
+ `handledNoteIds` refs, deferred baselines, and dual-track note decoding.
475
+ Returns `StreamedNote` objects that merge summary data with the underlying
476
+ record and pre-decode attachments.
477
+
478
+ Features:
479
+ - **Unified `StreamedNote` type** with sender (bech32), amount, assets, attachment, and `firstSeenAt` timestamp
480
+ - **Built-in filtering** by sender, status, `since` timestamp, `excludeIds`, and custom `amountFilter`
481
+ - **`markHandled` / `markAllHandled`** to exclude processed notes without removing them from the store
482
+ - **`snapshot()`** to capture current note IDs and timestamp for passing to the next phase
483
+
484
+ ```tsx
485
+ import { useNoteStream } from '@miden-sdk/react';
486
+
487
+ function IncomingNotes({ opponentId }: { opponentId: string }) {
488
+ const { notes, latest, markHandled, snapshot } = useNoteStream({
489
+ sender: opponentId, // Only notes from this sender
490
+ status: 'committed', // 'all' | 'consumed' | 'committed' | 'expected' | 'processing'
491
+ // since: phaseStartTime, // Only notes after this timestamp
492
+ // excludeIds: staleIds, // Exclude specific note IDs
493
+ // amountFilter: (a) => a >= 100n,
494
+ });
495
+
496
+ useEffect(() => {
497
+ if (latest) {
498
+ console.log('New note!', latest.attachment);
499
+ markHandled(latest.id);
500
+ }
501
+ }, [latest, markHandled]);
502
+
503
+ // Capture state for next phase
504
+ const handlePhaseEnd = () => {
505
+ const snap = snapshot(); // { ids: Set<string>, timestamp: number }
506
+ // Pass snap.ids as excludeIds or snap.timestamp as since to next phase
507
+ };
508
+
509
+ return <div>{notes.length} unhandled notes</div>;
510
+ }
511
+ ```
512
+
513
+ The `StreamedNote` type provides:
514
+ ```typescript
515
+ interface StreamedNote {
516
+ id: string; // Note ID (hex)
517
+ sender: string; // Sender account ID (bech32)
518
+ amount: bigint; // First fungible asset amount (0n if none)
519
+ assets: NoteAsset[]; // All assets on the note
520
+ record: InputNoteRecord; // Underlying record for escape-hatch access
521
+ firstSeenAt: number; // Timestamp (ms) when first observed
522
+ attachment: bigint[] | null; // Pre-decoded attachment values
523
+ }
524
+ ```
525
+
463
526
  #### `useAssetMetadata(assetIds)`
464
527
 
465
528
  Fetch asset symbols/decimals for a list of asset IDs. This is the lightweight
@@ -507,6 +570,12 @@ It collapses the multi-step transaction pipeline into a single call with stage
507
570
  tracking. You get private note delivery without having to remember the extra
508
571
  send step.
509
572
 
573
+ Built-in features:
574
+ - **Auto pre-sync** before executing (disable with `skipSync: true`)
575
+ - **Concurrency guard** prevents double-sends while a transaction is in-flight
576
+ - **Attachment support** for sending arbitrary data with notes
577
+ - **`sendAll`** to send the full balance of an asset
578
+
510
579
  ```tsx
511
580
  import { useSend } from '@miden-sdk/react';
512
581
 
@@ -529,8 +598,11 @@ function SendForm() {
529
598
  amount: 100n, // Amount in smallest units
530
599
 
531
600
  // Optional parameters
532
- noteType: 'private', // 'private' | 'public' | 'encrypted' (default: 'private')
601
+ noteType: 'private', // 'private' | 'public' (default: 'private')
533
602
  recallHeight: 1000, // Sender can reclaim after this block
603
+ attachment: [1n, 2n, 3n], // Arbitrary data payload
604
+ skipSync: false, // Skip auto-sync before send (default: false)
605
+ sendAll: false, // Send full balance (ignores amount)
534
606
  });
535
607
 
536
608
  console.log('Sent! TX:', transactionId);
@@ -561,6 +633,11 @@ each note to recipients via `sendPrivateNote`.
561
633
  It builds the request and executes the full pipeline in one go. That means
562
634
  fewer chances to handle batching incorrectly or forget private note delivery.
563
635
 
636
+ Built-in features:
637
+ - **Auto pre-sync** before executing (disable with `skipSync: true`)
638
+ - **Concurrency guard** prevents double-sends while a transaction is in-flight
639
+ - **Per-recipient note type and attachment overrides**
640
+
564
641
  ```tsx
565
642
  import { useMultiSend } from '@miden-sdk/react';
566
643
 
@@ -573,9 +650,10 @@ function MultiSendButton() {
573
650
  assetId: '0xtoken...',
574
651
  recipients: [
575
652
  { to: '0xrec1...', amount: 100n },
576
- { to: '0xrec2...', amount: 250n },
653
+ { to: '0xrec2...', amount: 250n, attachment: [42n] },
577
654
  ],
578
- noteType: 'public',
655
+ noteType: 'public', // Default for all recipients
656
+ skipSync: false, // Optional: skip auto-sync (default: false)
579
657
  });
580
658
  };
581
659
 
@@ -731,7 +809,7 @@ function MintForm() {
731
809
  faucetId: '0xmyfaucet...', // Your faucet ID
732
810
  targetAccountId: '0xwallet...', // Recipient wallet
733
811
  amount: 1000n * 10n**8n, // Amount to mint
734
- noteType: 'private', // Optional: 'private' | 'public' | 'encrypted'
812
+ noteType: 'private', // Optional: 'private' | 'public'
735
813
  });
736
814
 
737
815
  console.log('Minted! TX:', transactionId);
@@ -838,6 +916,10 @@ It standardizes the execute/prove/submit flow while still letting you craft the
838
916
  request. You get progress and error handling without wrapping every call
839
917
  yourself.
840
918
 
919
+ Built-in features:
920
+ - **Auto pre-sync** before executing (disable with `skipSync: true`)
921
+ - **Concurrency guard** prevents double-executions while a transaction is in-flight
922
+
841
923
  ```tsx
842
924
  import { useTransaction } from '@miden-sdk/react';
843
925
  import { AccountId, NoteType } from '@miden-sdk/miden-sdk';
@@ -858,6 +940,7 @@ function CustomTransactionButton({ accountId }: { accountId: string }) {
858
940
  NoteType.Private,
859
941
  NoteType.Private
860
942
  ),
943
+ skipSync: false, // Optional: skip auto-sync (default: false)
861
944
  });
862
945
  };
863
946
 
@@ -869,6 +952,152 @@ function CustomTransactionButton({ accountId }: { accountId: string }) {
869
952
  }
870
953
  ```
871
954
 
955
+ #### `useSessionAccount(options)`
956
+
957
+ Manage a session wallet lifecycle: create, fund, and consume in a single flow.
958
+ Replaces the common 300+ line pattern of creating a temporary wallet, waiting
959
+ for funding, and consuming the funding note. Persists the session wallet ID
960
+ to localStorage for page reloads.
961
+
962
+ ```tsx
963
+ import { useSessionAccount, useSend } from '@miden-sdk/react';
964
+
965
+ function SessionWallet({ mainWalletId, assetId }: { mainWalletId: string; assetId: string }) {
966
+ const { send } = useSend();
967
+ const { initialize, sessionAccountId, isReady, step, error, reset } =
968
+ useSessionAccount({
969
+ fund: async (sessionId) => {
970
+ // Send tokens from main wallet to session wallet
971
+ await send({ from: mainWalletId, to: sessionId, assetId, amount: 100n });
972
+ },
973
+ assetId,
974
+ // Optional:
975
+ // walletOptions: { storageMode: 'public', mutable: true, authScheme: 0 },
976
+ // pollIntervalMs: 3000,
977
+ // storagePrefix: 'miden-session',
978
+ });
979
+
980
+ if (error) return <div>Error: {error.message} <button onClick={reset}>Retry</button></div>;
981
+ if (isReady) return <div>Session ready: {sessionAccountId}</div>;
982
+
983
+ return (
984
+ <button onClick={initialize} disabled={step !== 'idle'}>
985
+ {step === 'idle' ? 'Start Session' : `${step}...`}
986
+ </button>
987
+ );
988
+ }
989
+ ```
990
+
991
+ Steps: `idle` -> `creating` -> `funding` -> `consuming` -> `ready`
992
+
993
+ ## Utilities
994
+
995
+ The SDK exports standalone utility functions for common tasks.
996
+
997
+ ### Note Attachments
998
+
999
+ Read and write arbitrary data payloads on notes:
1000
+
1001
+ ```typescript
1002
+ import { readNoteAttachment, createNoteAttachment } from '@miden-sdk/react';
1003
+
1004
+ // Read attachment from a note record
1005
+ const data = readNoteAttachment(noteRecord);
1006
+ if (data) {
1007
+ console.log(data.values); // bigint[]
1008
+ console.log(data.kind); // 'word' (<=4 values) or 'array' (>4 values)
1009
+ }
1010
+
1011
+ // Create attachment for sending
1012
+ const attachment = createNoteAttachment([1n, 2n, 3n]);
1013
+ // <= 4 values -> Word (auto-padded to 4)
1014
+ // > 4 values -> Array (auto-padded to multiple of 4)
1015
+ ```
1016
+
1017
+ ### Account ID Normalization
1018
+
1019
+ Compare and normalize account IDs across hex and bech32 formats:
1020
+
1021
+ ```typescript
1022
+ import { normalizeAccountId, accountIdsEqual } from '@miden-sdk/react';
1023
+
1024
+ const bech32 = normalizeAccountId('0x1234...'); // Returns bech32 format
1025
+ accountIdsEqual('0x1234...', 'miden1abc...'); // true (format-agnostic)
1026
+ ```
1027
+
1028
+ ### Byte Conversion
1029
+
1030
+ Utilities for bigint/byte conversions useful in cryptographic note data:
1031
+
1032
+ ```typescript
1033
+ import { bytesToBigInt, bigIntToBytes, concatBytes } from '@miden-sdk/react';
1034
+
1035
+ const n = bytesToBigInt(new Uint8Array([0x01, 0x00])); // 256n
1036
+ const bytes = bigIntToBytes(256n, 2); // Uint8Array([0x01, 0x00])
1037
+ const combined = concatBytes(bytes1, bytes2); // Concatenated Uint8Array
1038
+ ```
1039
+
1040
+ ### Storage Helpers
1041
+
1042
+ IndexedDB migration and namespaced localStorage persistence:
1043
+
1044
+ ```typescript
1045
+ import { migrateStorage, clearMidenStorage, createMidenStorage } from '@miden-sdk/react';
1046
+
1047
+ // Auto-clear stale IndexedDB when SDK version changes
1048
+ await migrateStorage({
1049
+ version: '0.13.1',
1050
+ // versionKey: 'miden:storageVersion', // default
1051
+ // reloadOnClear: true, // default
1052
+ // onBeforeClear: () => { /* save data */ },
1053
+ });
1054
+
1055
+ // Namespaced localStorage for app state
1056
+ const store = createMidenStorage('myapp');
1057
+ store.set('lastOpponent', '0x1234...');
1058
+ const opponent = store.get<string>('lastOpponent');
1059
+ store.remove('lastOpponent');
1060
+ store.clear(); // Clears only keys under 'myapp:' prefix
1061
+ ```
1062
+
1063
+ ### Wallet Detection
1064
+
1065
+ Wait for a browser extension wallet to be detected before connecting:
1066
+
1067
+ ```typescript
1068
+ import { waitForWalletDetection } from '@miden-sdk/react';
1069
+
1070
+ const adapter = wallets[0].adapter;
1071
+
1072
+ // Default 5s timeout
1073
+ await waitForWalletDetection(adapter);
1074
+
1075
+ // Custom timeout
1076
+ await waitForWalletDetection(adapter, 10000);
1077
+
1078
+ // Returns immediately if already installed, otherwise
1079
+ // listens for readyStateChange events with a timeout.
1080
+ ```
1081
+
1082
+ This replaces the common 30-line polling+timeout pattern needed when the wallet extension loads slowly. The adapter is duck-typed — any object with `readyState`, `on("readyStateChange", ...)`, and `off("readyStateChange", ...)` will work.
1083
+
1084
+ ### Error Handling Utilities
1085
+
1086
+ WASM errors are cryptic. The SDK wraps common patterns with actionable messages:
1087
+
1088
+ ```typescript
1089
+ import { MidenError, wrapWasmError } from '@miden-sdk/react';
1090
+
1091
+ try {
1092
+ await client.someMethod(accountId);
1093
+ } catch (e) {
1094
+ const wrapped = wrapWasmError(e);
1095
+ // MidenError with code: 'WASM_CLASS_MISMATCH' | 'WASM_POINTER_CONSUMED' |
1096
+ // 'WASM_NOT_INITIALIZED' | 'WASM_SYNC_REQUIRED' | 'SEND_BUSY' | 'UNKNOWN'
1097
+ console.log(wrapped.message); // Human-readable with fix suggestions
1098
+ }
1099
+ ```
1100
+
872
1101
  ## Common Patterns
873
1102
 
874
1103
  ### Error Handling
@@ -948,6 +1177,157 @@ function MyFeature() {
948
1177
  }
949
1178
  ```
950
1179
 
1180
+ ## External Signer Integration
1181
+
1182
+ For wallets using external key management, wrap your app with a signer provider **above** `MidenProvider`. The signer provider populates a `SignerContext` with a `signCb` and an `accountConfig`; `MidenProvider` picks these up automatically to create the client and initialize the account.
1183
+
1184
+ ### Para (EVM Wallets)
1185
+
1186
+ ```tsx
1187
+ import { ParaSignerProvider } from '@miden-sdk/para';
1188
+
1189
+ function App() {
1190
+ return (
1191
+ <ParaSignerProvider apiKey="your-api-key" environment="PRODUCTION">
1192
+ <MidenProvider config={{ rpcUrl: 'testnet' }}>
1193
+ <YourApp />
1194
+ </MidenProvider>
1195
+ </ParaSignerProvider>
1196
+ );
1197
+ }
1198
+
1199
+ // Access Para-specific data
1200
+ const { para, wallet, isConnected } = useParaSigner();
1201
+ ```
1202
+
1203
+ ### Turnkey
1204
+
1205
+ ```tsx
1206
+ import { TurnkeySignerProvider } from '@miden-sdk/miden-turnkey-react';
1207
+
1208
+ function App() {
1209
+ return (
1210
+ // Config is optional — defaults to https://api.turnkey.com
1211
+ // and reads VITE_TURNKEY_ORG_ID from environment
1212
+ <TurnkeySignerProvider>
1213
+ <MidenProvider config={{ rpcUrl: 'testnet' }}>
1214
+ <YourApp />
1215
+ </MidenProvider>
1216
+ </TurnkeySignerProvider>
1217
+ );
1218
+ }
1219
+
1220
+ // Or with explicit config:
1221
+ <TurnkeySignerProvider config={{
1222
+ apiBaseUrl: 'https://api.turnkey.com',
1223
+ defaultOrganizationId: 'your-org-id',
1224
+ }}>
1225
+ ...
1226
+ </TurnkeySignerProvider>
1227
+ ```
1228
+
1229
+ Connect via passkey authentication:
1230
+
1231
+ ```tsx
1232
+ import { useSigner } from '@miden-sdk/react';
1233
+ import { useTurnkeySigner } from '@miden-sdk/miden-turnkey-react';
1234
+
1235
+ const { isConnected, connect, disconnect } = useSigner();
1236
+ await connect(); // triggers passkey flow
1237
+
1238
+ const { client, account, setAccount } = useTurnkeySigner();
1239
+ ```
1240
+
1241
+ ### MidenFi Wallet Adapter
1242
+
1243
+ ```tsx
1244
+ import { MidenFiSignerProvider } from '@miden-sdk/wallet-adapter-react';
1245
+
1246
+ function App() {
1247
+ return (
1248
+ <MidenFiSignerProvider network="Testnet">
1249
+ <MidenProvider config={{ rpcUrl: 'testnet' }}>
1250
+ <YourApp />
1251
+ </MidenProvider>
1252
+ </MidenFiSignerProvider>
1253
+ );
1254
+ }
1255
+ ```
1256
+
1257
+ ### Unified Signer Hook
1258
+
1259
+ `useSigner()` works with any signer provider:
1260
+
1261
+ ```tsx
1262
+ import { useSigner } from '@miden-sdk/react';
1263
+
1264
+ function ConnectButton() {
1265
+ const signer = useSigner();
1266
+ if (!signer) return null; // local keystore mode
1267
+
1268
+ const { isConnected, connect, disconnect, name } = signer;
1269
+ return isConnected
1270
+ ? <button onClick={disconnect}>Disconnect {name}</button>
1271
+ : <button onClick={connect}>Connect with {name}</button>;
1272
+ }
1273
+ ```
1274
+
1275
+ ### Custom Account Components
1276
+
1277
+ Signer providers can include custom `AccountComponent` instances in the account via the `customComponents` field on `SignerAccountConfig`. This is useful for attaching application-specific logic compiled from `.masp` packages (e.g. a DEX component or custom smart contract) alongside the default auth and basic wallet components.
1278
+
1279
+ Pre-built signer providers (Para, Turnkey, MidenFi) accept `customComponents` as a prop and forward it into `accountConfig`:
1280
+
1281
+ ```tsx
1282
+ import { ParaSignerProvider } from '@miden-sdk/para';
1283
+ import type { AccountComponent } from '@miden-sdk/miden-sdk';
1284
+
1285
+ const dexComponent: AccountComponent = await loadCompiledComponent();
1286
+
1287
+ <ParaSignerProvider
1288
+ apiKey="your-api-key"
1289
+ environment="PRODUCTION"
1290
+ customComponents={[dexComponent]}
1291
+ >
1292
+ <MidenProvider config={{ rpcUrl: 'testnet' }}>
1293
+ <YourApp />
1294
+ </MidenProvider>
1295
+ </ParaSignerProvider>
1296
+ ```
1297
+
1298
+ When building a custom signer provider, pass `customComponents` through the `SignerContext` directly:
1299
+
1300
+ ```tsx
1301
+ import { SignerContext } from '@miden-sdk/react';
1302
+ import type { AccountComponent } from '@miden-sdk/miden-sdk';
1303
+
1304
+ function MySignerProvider({ children, customComponents }: {
1305
+ children: React.ReactNode;
1306
+ customComponents?: AccountComponent[];
1307
+ }) {
1308
+ return (
1309
+ <SignerContext.Provider value={{
1310
+ name: 'MySigner',
1311
+ storeName: `mysigner_${userId}`,
1312
+ isConnected: true,
1313
+ accountConfig: {
1314
+ publicKeyCommitment: userPublicKeyCommitment,
1315
+ accountType: 'RegularAccountUpdatableCode',
1316
+ storageMode: myStorageMode,
1317
+ customComponents,
1318
+ },
1319
+ signCb: async (pubKey, signingInputs) => signature,
1320
+ connect: async () => { /* ... */ },
1321
+ disconnect: async () => { /* ... */ },
1322
+ }}>
1323
+ {children}
1324
+ </SignerContext.Provider>
1325
+ );
1326
+ }
1327
+ ```
1328
+
1329
+ Components are appended to the `AccountBuilder` after the default basic wallet component and before `build()` is called, so the account always includes wallet functionality plus any extras you provide. The field is optional — omitting it or passing an empty array preserves the default behavior.
1330
+
951
1331
  ## Default Values
952
1332
 
953
1333
  The SDK uses privacy-first defaults:
@@ -957,7 +1337,8 @@ The SDK uses privacy-first defaults:
957
1337
  | `storageMode` | `'private'` | Account data stored off-chain |
958
1338
  | `mutable` | `true` | Wallet code can be updated |
959
1339
  | `authScheme` | `0` (Falcon) | Post-quantum secure signatures |
960
- | `noteType` | `'private'` | Note contents encrypted |
1340
+ | `noteType` | `'private'` | Note contents are private |
1341
+ | `skipSync` | `false` | Auto-sync before transactions |
961
1342
  | `decimals` | `8` | Token decimal places |
962
1343
  | `autoSyncInterval` | `15000` | Sync every 15 seconds |
963
1344
 
@@ -988,6 +1369,16 @@ import type {
988
1369
  ExecuteTransactionOptions,
989
1370
  NotesFilter,
990
1371
 
1372
+ // Note stream types
1373
+ StreamedNote,
1374
+ UseNoteStreamOptions,
1375
+ UseNoteStreamReturn,
1376
+
1377
+ // Session account types
1378
+ UseSessionAccountOptions,
1379
+ UseSessionAccountReturn,
1380
+ SessionAccountStep,
1381
+
991
1382
  // Hook results
992
1383
  AccountResult,
993
1384
  AccountsResult,
@@ -998,6 +1389,11 @@ import type {
998
1389
  TransactionStage,
999
1390
  AssetBalance,
1000
1391
  SyncState,
1392
+
1393
+ // Utility types
1394
+ NoteAttachmentData,
1395
+ MidenErrorCode,
1396
+ MigrateStorageOptions,
1001
1397
  } from '@miden-sdk/react';
1002
1398
  ```
1003
1399
 
@@ -1016,7 +1412,7 @@ yarn dev
1016
1412
  ## Requirements
1017
1413
 
1018
1414
  - React 18.0 or higher
1019
- - `@miden-sdk/miden-sdk` ^0.13.0-0
1415
+ - `@miden-sdk/miden-sdk` ^0.13.1
1020
1416
 
1021
1417
  ## Browser Support
1022
1418