create-miden-app 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/.claude/commands/review-security.md +67 -0
- package/template/.claude/settings.json +1 -7
- package/template/.claude/settings.local.json +24 -0
- package/template/.claude/skills/frontend-pitfalls/SKILL.md +28 -31
- package/template/.claude/skills/frontend-source-guide/SKILL.md +14 -14
- package/template/.claude/skills/miden-concepts/SKILL.md +4 -2
- package/template/.claude/skills/react-sdk-patterns/SKILL.md +294 -28
- package/template/.claude/skills/signer-integration/SKILL.md +22 -3
- package/template/.claude/skills/testing-patterns/SKILL.md +201 -40
- package/template/.claude/skills/vite-wasm-setup/SKILL.md +20 -14
- package/template/.claude/skills/web-client-usage/SKILL.md +454 -0
- package/template/.env.example +15 -2
- package/template/.mcp.json +9 -0
- package/template/CLAUDE.md +49 -16
- package/template/README.md +85 -19
- package/template/package.json +5 -4
- package/template/public/packages/counter_account.masp +0 -0
- package/template/public/packages/increment_note.masp +0 -0
- package/template/src/__tests__/fixtures/accounts.ts +17 -6
- package/template/src/__tests__/fixtures/index.ts +1 -0
- package/template/src/__tests__/mocks/miden-sdk-react.ts +18 -1
- package/template/src/__tests__/patterns/mutation-hook.test.tsx +2 -2
- package/template/src/__tests__/patterns/provider-setup.test.tsx +2 -0
- package/template/src/components/AppContent.tsx +33 -3
- package/template/{create-miden-app/template/src/components/Counter.tsx → src/components/ConfiguredCounter.tsx} +7 -4
- package/template/src/components/Counter.tsx +12 -41
- package/template/src/components/__tests__/AppContent.test.tsx +192 -4
- package/template/src/components/__tests__/ConfiguredCounter.test.tsx +116 -0
- package/template/src/components/__tests__/Counter.test.tsx +24 -94
- package/template/src/config.ts +26 -6
- package/template/src/hooks/__tests__/useIncrementCounter.test.tsx +257 -0
- package/template/src/hooks/useIncrementCounter.ts +109 -50
- package/template/src/providers.tsx +20 -24
- package/template/vite.config.ts +1 -1
- package/template/vitest.config.ts +1 -2
- package/template/yarn.lock +761 -688
- package/template/create-miden-app/template/.claude/hooks/typecheck.sh +0 -27
- package/template/create-miden-app/template/.claude/settings.json +0 -17
- package/template/create-miden-app/template/.claude/skills/frontend-pitfalls/SKILL.md +0 -189
- package/template/create-miden-app/template/.claude/skills/frontend-source-guide/SKILL.md +0 -163
- package/template/create-miden-app/template/.claude/skills/miden-concepts/SKILL.md +0 -108
- package/template/create-miden-app/template/.claude/skills/react-sdk-patterns/SKILL.md +0 -294
- package/template/create-miden-app/template/.claude/skills/signer-integration/SKILL.md +0 -158
- package/template/create-miden-app/template/.claude/skills/vite-wasm-setup/SKILL.md +0 -128
- package/template/create-miden-app/template/.env.example +0 -5
- package/template/create-miden-app/template/CLAUDE.md +0 -116
- package/template/create-miden-app/template/README.md +0 -61
- package/template/create-miden-app/template/eslint.config.js +0 -23
- package/template/create-miden-app/template/index.html +0 -13
- package/template/create-miden-app/template/package.json +0 -34
- package/template/create-miden-app/template/public/vite.svg +0 -1
- package/template/create-miden-app/template/src/App.tsx +0 -10
- package/template/create-miden-app/template/src/assets/miden.svg +0 -3
- package/template/create-miden-app/template/src/assets/react.svg +0 -1
- package/template/create-miden-app/template/src/components/AppContent.css +0 -45
- package/template/create-miden-app/template/src/components/AppContent.tsx +0 -50
- package/template/create-miden-app/template/src/components/Counter.css +0 -27
- package/template/create-miden-app/template/src/config.ts +0 -21
- package/template/create-miden-app/template/src/hooks/useIncrementCounter.ts +0 -136
- package/template/create-miden-app/template/src/index.css +0 -75
- package/template/create-miden-app/template/src/lib/miden.ts +0 -9
- package/template/create-miden-app/template/src/main.tsx +0 -10
- package/template/create-miden-app/template/src/providers.tsx +0 -31
- package/template/create-miden-app/template/src/vite-env.d.ts +0 -1
- package/template/create-miden-app/template/tsconfig.app.json +0 -32
- package/template/create-miden-app/template/tsconfig.json +0 -7
- package/template/create-miden-app/template/tsconfig.node.json +0 -24
- package/template/create-miden-app/template/vite.config.ts +0 -17
- package/template/create-miden-app/template/yarn.lock +0 -1697
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# Miden Frontend Template
|
|
2
|
-
|
|
3
|
-
Minimal Vite + React + TypeScript template for building Miden frontends. Includes a network counter demo that publishes an increment note via the MidenFi wallet adapter.
|
|
4
|
-
|
|
5
|
-
## Getting Started
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
yarn install
|
|
9
|
-
yarn dev
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
Open [http://localhost:5173](http://localhost:5173). Connect your MidenFi wallet and click the counter button to publish an increment note.
|
|
13
|
-
|
|
14
|
-
## Project Structure
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
src/
|
|
18
|
-
├── App.tsx # Root component
|
|
19
|
-
├── providers.tsx # MidenProvider + wallet adapter setup
|
|
20
|
-
├── config.ts # Constants (counter address, explorer URL, SDK config)
|
|
21
|
-
├── components/
|
|
22
|
-
│ ├── AppContent.tsx # Page layout, logos, wallet button
|
|
23
|
-
│ └── Counter.tsx # Counter UI
|
|
24
|
-
├── hooks/
|
|
25
|
-
│ └── useIncrementCounter.ts # Note construction, wallet submission, re-sync
|
|
26
|
-
└── lib/
|
|
27
|
-
└── miden.ts # Shared Miden utilities
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Network Counter Demo
|
|
31
|
-
|
|
32
|
-
The template demonstrates the network note pattern on Miden testnet:
|
|
33
|
-
|
|
34
|
-
1. A **counter account** is deployed as a network account (`AccountStorageMode::Network`) at [`mtst1aru8adnrqspgcsr3drk2n990lyc070ll`](https://testnet.midenscan.com/account/mtst1aru8adnrqspgcsr3drk2n990lyc070ll)
|
|
35
|
-
2. On button click, the frontend constructs a **public note** targeting the counter and submits it through the wallet adapter
|
|
36
|
-
3. The **network operator** picks up the note and executes it against the counter account, incrementing the on-chain count
|
|
37
|
-
4. The frontend re-syncs and reads the updated count from the counter's `StorageMap`
|
|
38
|
-
|
|
39
|
-
Pre-compiled `.masp` packages for the counter account and increment note are in `public/packages/`.
|
|
40
|
-
|
|
41
|
-
## Key Dependencies
|
|
42
|
-
|
|
43
|
-
| Package | Purpose |
|
|
44
|
-
|---------|---------|
|
|
45
|
-
| `@miden-sdk/react` | React hooks for Miden (useAccount, useSyncState, useImportAccount, etc.) |
|
|
46
|
-
| `@miden-sdk/miden-sdk` | Core SDK types (Note, NoteScript, AccountId, Word, etc.) |
|
|
47
|
-
| `@miden-sdk/vite-plugin` | Vite plugin handling WASM loading, top-level await, and COOP/COEP |
|
|
48
|
-
| `@demox-labs/miden-wallet-adapter` | MidenFi wallet adapter for transaction submission |
|
|
49
|
-
|
|
50
|
-
## Configuration
|
|
51
|
-
|
|
52
|
-
SDK settings can be overridden via environment variables (see `.env.example`):
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
VITE_MIDEN_RPC_URL=testnet # "testnet" | "localhost" | custom URL
|
|
56
|
-
VITE_MIDEN_PROVER=testnet # "testnet" | "local"
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## AI Developer Experience
|
|
60
|
-
|
|
61
|
-
This template ships with `.claude/` skills for AI coding tools. Skills cover React SDK patterns, frontend pitfalls, Vite + WASM setup, signer integration, and Miden architecture. See `CLAUDE.md` for the full developer guide.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import js from '@eslint/js'
|
|
2
|
-
import globals from 'globals'
|
|
3
|
-
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
-
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
-
import tseslint from 'typescript-eslint'
|
|
6
|
-
import { defineConfig, globalIgnores } from 'eslint/config'
|
|
7
|
-
|
|
8
|
-
export default defineConfig([
|
|
9
|
-
globalIgnores(['dist']),
|
|
10
|
-
{
|
|
11
|
-
files: ['**/*.{ts,tsx}'],
|
|
12
|
-
extends: [
|
|
13
|
-
js.configs.recommended,
|
|
14
|
-
tseslint.configs.recommended,
|
|
15
|
-
reactHooks.configs['recommended-latest'],
|
|
16
|
-
reactRefresh.configs.vite,
|
|
17
|
-
],
|
|
18
|
-
languageOptions: {
|
|
19
|
-
ecmaVersion: 2020,
|
|
20
|
-
globals: globals.browser,
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
])
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>Miden Template</title>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="root"></div>
|
|
11
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "miden-app",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "0.0.0",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "tsc -b && vite build",
|
|
9
|
-
"lint": "eslint .",
|
|
10
|
-
"preview": "vite preview"
|
|
11
|
-
},
|
|
12
|
-
"dependencies": {
|
|
13
|
-
"@demox-labs/miden-wallet-adapter": "0.10.0",
|
|
14
|
-
"@miden-sdk/miden-sdk": "0.13.2",
|
|
15
|
-
"@miden-sdk/react": "0.13.3",
|
|
16
|
-
"react": "^19.1.1",
|
|
17
|
-
"react-dom": "^19.1.1"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@eslint/js": "^9.36.0",
|
|
21
|
-
"@miden-sdk/vite-plugin": "0.13.4",
|
|
22
|
-
"@types/node": "^24.6.0",
|
|
23
|
-
"@types/react": "^19.1.16",
|
|
24
|
-
"@types/react-dom": "^19.1.9",
|
|
25
|
-
"@vitejs/plugin-react": "^4.7.0",
|
|
26
|
-
"eslint": "^9.36.0",
|
|
27
|
-
"eslint-plugin-react-hooks": "^5.2.0",
|
|
28
|
-
"eslint-plugin-react-refresh": "^0.4.22",
|
|
29
|
-
"globals": "^16.4.0",
|
|
30
|
-
"typescript": "~5.7.0",
|
|
31
|
-
"typescript-eslint": "^8.45.0",
|
|
32
|
-
"vite": "^6.0.0"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg width="605" height="838" viewBox="0 0 605 838" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M300.929 247.947L351.073 303.14C355.354 307.84 363.172 304.815 363.172 298.486V166.322C363.172 164.479 363.901 162.71 365.2 161.402C366.499 160.095 368.263 159.354 370.106 159.341H462.249C502.689 159.341 540.151 180.469 560.883 214.953L579.079 245.202C580.288 247.207 581.994 248.867 584.032 250.021C586.07 251.174 588.371 251.782 590.713 251.787H591.411C595.017 251.78 598.474 250.344 601.021 247.791C603.569 245.239 605 241.781 605 238.175V100.705C605 97.0992 603.569 93.6405 601.021 91.0884C598.474 88.5363 595.017 87.0995 591.411 87.0933H377.063C373.379 87.0933 369.846 85.6298 367.241 83.0247C364.636 80.4196 363.172 76.8863 363.172 73.2022V10.4242C363.172 4.67693 358.519 0 352.748 0H304.14C298.393 0 293.716 4.65367 293.716 10.4242V73.2022C293.716 80.8807 287.504 87.1166 279.825 87.1166H13.6352C10.0332 87.1166 6.57795 88.5443 4.02654 91.087C1.47513 93.6297 0.0355831 97.08 0.0232683 100.682V133.118C0.0232683 136.608 1.37283 139.959 3.76947 142.495L302.465 409.476C304.853 411.996 306.184 415.335 306.184 418.807C306.184 422.278 304.853 425.617 302.465 428.137L3.7462 695.141C1.34344 697.672 0.00267442 701.028 0 704.518V736.954C0 744.47 6.0963 750.543 13.612 750.543H279.802C287.48 750.543 293.693 756.779 293.693 764.458V827.235C293.693 832.983 298.347 837.66 304.117 837.66H352.725C358.472 837.66 363.149 833.006 363.149 827.235V764.458C363.149 756.779 369.362 750.566 377.017 750.566H591.365C593.158 750.569 594.934 750.218 596.592 749.532C598.249 748.847 599.754 747.841 601.021 746.571C602.288 745.302 603.292 743.795 603.975 742.137C604.658 740.478 605.006 738.701 605 736.908V599.462C605 595.852 603.566 592.389 601.013 589.837C598.46 587.284 594.998 585.85 591.388 585.85H590.736C588.387 585.846 586.076 586.45 584.029 587.604C581.982 588.758 580.269 590.422 579.056 592.435L560.883 622.684C550.636 639.669 536.17 653.715 518.892 663.459C501.613 673.203 482.109 678.314 462.272 678.295H370.106C369.192 678.292 368.288 678.109 367.445 677.756C366.603 677.404 365.837 676.889 365.193 676.241C364.55 675.593 364.04 674.824 363.693 673.979C363.346 673.133 363.169 672.228 363.172 671.314V539.15C363.178 537.744 362.756 536.369 361.962 535.208C361.168 534.047 360.04 533.155 358.727 532.651C357.415 532.146 355.98 532.052 354.613 532.382C353.245 532.711 352.011 533.449 351.073 534.497L300.929 589.689C296.276 594.808 293.716 601.463 293.716 608.397V671.338C293.716 673.177 292.986 674.94 291.685 676.241C290.385 677.541 288.621 678.272 286.782 678.272H115.9C115.511 678.282 115.126 678.191 114.783 678.008C114.44 677.824 114.151 677.554 113.945 677.225C113.716 676.835 113.614 676.385 113.651 675.935C113.689 675.485 113.864 675.058 114.154 674.712L380.414 424.507L380.461 424.438C381.755 422.842 382.461 420.85 382.461 418.795C382.461 416.74 381.755 414.748 380.461 413.152L380.414 413.106L114.154 162.925C113.864 162.579 113.689 162.151 113.651 161.702C113.614 161.252 113.716 160.801 113.945 160.412C114.151 160.082 114.44 159.812 114.783 159.629C115.126 159.445 115.511 159.354 115.9 159.365H286.782C290.598 159.365 293.716 162.459 293.716 166.299V229.24C293.716 236.15 296.276 242.828 300.929 247.947Z" fill="#FF5500"/>
|
|
3
|
-
</svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
.logo {
|
|
2
|
-
height: 6em;
|
|
3
|
-
padding: 1.5em;
|
|
4
|
-
will-change: filter;
|
|
5
|
-
transition: filter 300ms;
|
|
6
|
-
}
|
|
7
|
-
.logo:hover {
|
|
8
|
-
filter: drop-shadow(0 0 2em #646cffaa);
|
|
9
|
-
}
|
|
10
|
-
.logo.react:hover {
|
|
11
|
-
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
12
|
-
}
|
|
13
|
-
.logo.miden:hover {
|
|
14
|
-
filter: drop-shadow(0 0 2em #ff5500);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@keyframes logo-spin {
|
|
18
|
-
from {
|
|
19
|
-
transform: rotate(0deg);
|
|
20
|
-
}
|
|
21
|
-
to {
|
|
22
|
-
transform: rotate(360deg);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
27
|
-
a:nth-of-type(2) .logo {
|
|
28
|
-
animation: logo-spin infinite 20s linear;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.wallet-section {
|
|
33
|
-
display: flex;
|
|
34
|
-
justify-content: center;
|
|
35
|
-
margin-bottom: 1rem;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.loading {
|
|
39
|
-
padding: 2rem;
|
|
40
|
-
color: #888;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.read-the-docs {
|
|
44
|
-
color: #888;
|
|
45
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { useMiden, useSyncState } from "@miden-sdk/react";
|
|
2
|
-
import { WalletMultiButton } from "@demox-labs/miden-wallet-adapter";
|
|
3
|
-
import reactLogo from "@/assets/react.svg";
|
|
4
|
-
import midenLogo from "@/assets/miden.svg";
|
|
5
|
-
import viteLogo from "/vite.svg";
|
|
6
|
-
import { Counter } from "@/components/Counter";
|
|
7
|
-
import "./AppContent.css";
|
|
8
|
-
|
|
9
|
-
export function AppContent() {
|
|
10
|
-
const { isReady, isInitializing, error } = useMiden();
|
|
11
|
-
const { syncHeight } = useSyncState();
|
|
12
|
-
|
|
13
|
-
if (error) {
|
|
14
|
-
return (
|
|
15
|
-
<div className="loading">
|
|
16
|
-
<p>Failed to initialize Miden client</p>
|
|
17
|
-
<p className="error">{error.message}</p>
|
|
18
|
-
</div>
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (isInitializing || !isReady) {
|
|
23
|
-
return <div className="loading">Initializing Miden client...</div>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<>
|
|
28
|
-
<div>
|
|
29
|
-
<a href="https://vite.dev" target="_blank" rel="noreferrer">
|
|
30
|
-
<img src={viteLogo} className="logo" alt="Vite logo" />
|
|
31
|
-
</a>
|
|
32
|
-
<a href="https://react.dev" target="_blank" rel="noreferrer">
|
|
33
|
-
<img src={reactLogo} className="logo react" alt="React logo" />
|
|
34
|
-
</a>
|
|
35
|
-
<a href="https://docs.miden.io" target="_blank" rel="noreferrer">
|
|
36
|
-
<img src={midenLogo} className="logo miden" alt="Miden logo" />
|
|
37
|
-
</a>
|
|
38
|
-
</div>
|
|
39
|
-
<h1>Vite + React + Miden</h1>
|
|
40
|
-
<div className="wallet-section">
|
|
41
|
-
<WalletMultiButton />
|
|
42
|
-
</div>
|
|
43
|
-
<Counter />
|
|
44
|
-
<p className="read-the-docs">
|
|
45
|
-
Testnet block: {syncHeight ?? "syncing..."} | Click on the Vite, React,
|
|
46
|
-
and Miden logos to learn more
|
|
47
|
-
</p>
|
|
48
|
-
</>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
.card {
|
|
2
|
-
padding: 2em;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.counter-button {
|
|
6
|
-
font-size: 1.2em;
|
|
7
|
-
padding: 0.8em 1.6em;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.account-id {
|
|
11
|
-
font-size: 0.8em;
|
|
12
|
-
color: #888;
|
|
13
|
-
font-family: monospace;
|
|
14
|
-
margin-top: 0.5rem;
|
|
15
|
-
text-decoration: none;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.account-id:hover {
|
|
19
|
-
text-decoration: underline;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.error {
|
|
23
|
-
color: #ff4444;
|
|
24
|
-
font-size: 0.9em;
|
|
25
|
-
margin-top: 0.5rem;
|
|
26
|
-
word-break: break-word;
|
|
27
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Network counter account deployed on Miden testnet
|
|
2
|
-
export const COUNTER_ADDRESS = "mtst1aru8adnrqspgcsr3drk2n990lyc070ll";
|
|
3
|
-
|
|
4
|
-
// StorageMap slot name for the counter
|
|
5
|
-
export const COUNTER_SLOT_NAME =
|
|
6
|
-
"miden::component::miden_counter_account::count_map";
|
|
7
|
-
|
|
8
|
-
// Block explorer base URL
|
|
9
|
-
export const EXPLORER_BASE_URL = "https://testnet.midenscan.com";
|
|
10
|
-
|
|
11
|
-
// Delay (ms) to wait for the network to process a note before re-syncing
|
|
12
|
-
export const NETWORK_SYNC_DELAY_MS = 10_000;
|
|
13
|
-
|
|
14
|
-
// Application display name (used by wallet adapter)
|
|
15
|
-
export const APP_NAME = "Miden Template";
|
|
16
|
-
|
|
17
|
-
// Miden SDK configuration — override via environment variables
|
|
18
|
-
export const MIDEN_RPC_URL =
|
|
19
|
-
import.meta.env.VITE_MIDEN_RPC_URL ?? "testnet";
|
|
20
|
-
export const MIDEN_PROVER =
|
|
21
|
-
(import.meta.env.VITE_MIDEN_PROVER as "testnet" | "local") ?? "testnet";
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { useMemo, useState, useCallback, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
useSyncState,
|
|
4
|
-
useAccount,
|
|
5
|
-
useImportAccount,
|
|
6
|
-
} from "@miden-sdk/react";
|
|
7
|
-
import {
|
|
8
|
-
useWallet,
|
|
9
|
-
Transaction,
|
|
10
|
-
} from "@demox-labs/miden-wallet-adapter";
|
|
11
|
-
import {
|
|
12
|
-
TransactionRequestBuilder,
|
|
13
|
-
Package,
|
|
14
|
-
NoteScript,
|
|
15
|
-
Note,
|
|
16
|
-
NoteAssets,
|
|
17
|
-
NoteMetadata,
|
|
18
|
-
NoteRecipient,
|
|
19
|
-
NoteInputs,
|
|
20
|
-
NoteTag,
|
|
21
|
-
NoteType,
|
|
22
|
-
NoteAttachment,
|
|
23
|
-
NoteExecutionHint,
|
|
24
|
-
OutputNote,
|
|
25
|
-
OutputNoteArray,
|
|
26
|
-
AccountId,
|
|
27
|
-
Felt,
|
|
28
|
-
FeltArray,
|
|
29
|
-
Word,
|
|
30
|
-
} from "@miden-sdk/miden-sdk";
|
|
31
|
-
import { randomWord } from "@/lib/miden";
|
|
32
|
-
import {
|
|
33
|
-
COUNTER_SLOT_NAME,
|
|
34
|
-
EXPLORER_BASE_URL,
|
|
35
|
-
NETWORK_SYNC_DELAY_MS,
|
|
36
|
-
} from "@/config";
|
|
37
|
-
|
|
38
|
-
export function useIncrementCounter(counterAddress: string) {
|
|
39
|
-
const [error, setError] = useState<string | null>(null);
|
|
40
|
-
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
41
|
-
const [isWaiting, setIsWaiting] = useState(false);
|
|
42
|
-
|
|
43
|
-
const { address: walletAddress, connected, requestTransaction } = useWallet();
|
|
44
|
-
const { importAccount } = useImportAccount();
|
|
45
|
-
const { account, refetch } = useAccount(counterAddress);
|
|
46
|
-
const { sync } = useSyncState();
|
|
47
|
-
|
|
48
|
-
// Import the counter account so the local client tracks it.
|
|
49
|
-
// The catch is intentional — the account may already be imported.
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
importAccount({ type: "id", accountId: counterAddress }).catch(() => {});
|
|
52
|
-
}, [importAccount, counterAddress]);
|
|
53
|
-
|
|
54
|
-
// Read count from StorageMap
|
|
55
|
-
const count = useMemo(() => {
|
|
56
|
-
if (!account) return null;
|
|
57
|
-
const countKey = Word.newFromFelts([
|
|
58
|
-
new Felt(0n),
|
|
59
|
-
new Felt(0n),
|
|
60
|
-
new Felt(0n),
|
|
61
|
-
new Felt(1n),
|
|
62
|
-
]);
|
|
63
|
-
const value = account.storage().getMapItem(COUNTER_SLOT_NAME, countKey);
|
|
64
|
-
return value ? Number(value.toU64s()[3]) : 0;
|
|
65
|
-
}, [account]);
|
|
66
|
-
|
|
67
|
-
const increment = useCallback(async () => {
|
|
68
|
-
if (!walletAddress || !requestTransaction) return;
|
|
69
|
-
setError(null);
|
|
70
|
-
setIsSubmitting(true);
|
|
71
|
-
try {
|
|
72
|
-
// Load pre-compiled increment-note package
|
|
73
|
-
const buf = await fetch("/packages/increment_note.masp").then((r) =>
|
|
74
|
-
r.arrayBuffer(),
|
|
75
|
-
);
|
|
76
|
-
const pkg = Package.deserialize(new Uint8Array(buf));
|
|
77
|
-
const noteScript = NoteScript.fromPackage(pkg);
|
|
78
|
-
|
|
79
|
-
const counterAccountId = AccountId.fromBech32(counterAddress);
|
|
80
|
-
const walletAccountId = AccountId.fromBech32(walletAddress);
|
|
81
|
-
|
|
82
|
-
// Build note recipient
|
|
83
|
-
const serialNum = randomWord();
|
|
84
|
-
const inputs = new NoteInputs(new FeltArray());
|
|
85
|
-
const recipient = new NoteRecipient(serialNum, noteScript, inputs);
|
|
86
|
-
|
|
87
|
-
// Build note metadata targeting the network counter account
|
|
88
|
-
const tag = NoteTag.withAccountTarget(counterAccountId);
|
|
89
|
-
const attachment = NoteAttachment.newNetworkAccountTarget(
|
|
90
|
-
counterAccountId,
|
|
91
|
-
NoteExecutionHint.always(),
|
|
92
|
-
);
|
|
93
|
-
const metadata = new NoteMetadata(
|
|
94
|
-
walletAccountId,
|
|
95
|
-
NoteType.Public,
|
|
96
|
-
tag,
|
|
97
|
-
).withAttachment(attachment);
|
|
98
|
-
|
|
99
|
-
// Assemble the note and submit via wallet adapter
|
|
100
|
-
const note = new Note(new NoteAssets(), metadata, recipient);
|
|
101
|
-
const outputNote = OutputNote.full(note);
|
|
102
|
-
const txRequest = new TransactionRequestBuilder()
|
|
103
|
-
.withOwnOutputNotes(new OutputNoteArray([outputNote]))
|
|
104
|
-
.build();
|
|
105
|
-
|
|
106
|
-
const tx = Transaction.createCustomTransaction(
|
|
107
|
-
walletAddress,
|
|
108
|
-
counterAddress,
|
|
109
|
-
txRequest,
|
|
110
|
-
);
|
|
111
|
-
await requestTransaction(tx);
|
|
112
|
-
setIsSubmitting(false);
|
|
113
|
-
|
|
114
|
-
// Wait for network to process the note, then re-sync
|
|
115
|
-
setIsWaiting(true);
|
|
116
|
-
await new Promise((r) => setTimeout(r, NETWORK_SYNC_DELAY_MS));
|
|
117
|
-
await sync();
|
|
118
|
-
await refetch();
|
|
119
|
-
setIsWaiting(false);
|
|
120
|
-
} catch (err) {
|
|
121
|
-
setIsSubmitting(false);
|
|
122
|
-
setIsWaiting(false);
|
|
123
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
124
|
-
}
|
|
125
|
-
}, [walletAddress, requestTransaction, counterAddress, sync, refetch]);
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
increment,
|
|
129
|
-
count,
|
|
130
|
-
isSubmitting,
|
|
131
|
-
isWaiting,
|
|
132
|
-
error,
|
|
133
|
-
walletConnected: connected,
|
|
134
|
-
explorerUrl: `${EXPLORER_BASE_URL}/account/${counterAddress}`,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
-
line-height: 1.5;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
color: rgba(255, 255, 255, 0.87);
|
|
8
|
-
background-color: #242424;
|
|
9
|
-
|
|
10
|
-
font-synthesis: none;
|
|
11
|
-
text-rendering: optimizeLegibility;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
a {
|
|
17
|
-
font-weight: 500;
|
|
18
|
-
color: #646cff;
|
|
19
|
-
text-decoration: inherit;
|
|
20
|
-
}
|
|
21
|
-
a:hover {
|
|
22
|
-
color: #535bf2;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
body {
|
|
26
|
-
margin: 0;
|
|
27
|
-
display: flex;
|
|
28
|
-
place-items: center;
|
|
29
|
-
min-width: 320px;
|
|
30
|
-
min-height: 100vh;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
h1 {
|
|
34
|
-
font-size: 3.2em;
|
|
35
|
-
line-height: 1.1;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
button {
|
|
39
|
-
border-radius: 8px;
|
|
40
|
-
border: 1px solid transparent;
|
|
41
|
-
padding: 0.6em 1.2em;
|
|
42
|
-
font-size: 1em;
|
|
43
|
-
font-weight: 500;
|
|
44
|
-
font-family: inherit;
|
|
45
|
-
background-color: #1a1a1a;
|
|
46
|
-
cursor: pointer;
|
|
47
|
-
transition: border-color 0.25s;
|
|
48
|
-
}
|
|
49
|
-
button:hover {
|
|
50
|
-
border-color: #646cff;
|
|
51
|
-
}
|
|
52
|
-
button:focus,
|
|
53
|
-
button:focus-visible {
|
|
54
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#root {
|
|
58
|
-
max-width: 1280px;
|
|
59
|
-
margin: 0 auto;
|
|
60
|
-
padding: 2rem;
|
|
61
|
-
text-align: center;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@media (prefers-color-scheme: light) {
|
|
65
|
-
:root {
|
|
66
|
-
color: #213547;
|
|
67
|
-
background-color: #ffffff;
|
|
68
|
-
}
|
|
69
|
-
a:hover {
|
|
70
|
-
color: #747bff;
|
|
71
|
-
}
|
|
72
|
-
button {
|
|
73
|
-
background-color: #f9f9f9;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Felt, Word } from "@miden-sdk/miden-sdk";
|
|
2
|
-
|
|
3
|
-
/** Generate a random 4-felt Word (used as note serial number). */
|
|
4
|
-
export function randomWord(): Word {
|
|
5
|
-
const felts = Array.from({ length: 4 }, () =>
|
|
6
|
-
new Felt(BigInt(Math.floor(Math.random() * 2 ** 32))),
|
|
7
|
-
);
|
|
8
|
-
return Word.newFromFelts(felts);
|
|
9
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { useMemo, type ReactNode } from "react";
|
|
2
|
-
import { MidenProvider } from "@miden-sdk/react";
|
|
3
|
-
import {
|
|
4
|
-
MidenWalletAdapter,
|
|
5
|
-
WalletProvider,
|
|
6
|
-
WalletModalProvider,
|
|
7
|
-
} from "@demox-labs/miden-wallet-adapter";
|
|
8
|
-
import "@demox-labs/miden-wallet-adapter/styles.css";
|
|
9
|
-
import { APP_NAME, MIDEN_RPC_URL, MIDEN_PROVER } from "@/config";
|
|
10
|
-
|
|
11
|
-
export function AppProviders({ children }: { children: ReactNode }) {
|
|
12
|
-
const wallets = useMemo(
|
|
13
|
-
() => [new MidenWalletAdapter({ appName: APP_NAME })],
|
|
14
|
-
[],
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<WalletProvider wallets={wallets} autoConnect>
|
|
19
|
-
<WalletModalProvider>
|
|
20
|
-
<MidenProvider
|
|
21
|
-
config={{ rpcUrl: MIDEN_RPC_URL, prover: MIDEN_PROVER }}
|
|
22
|
-
loadingComponent={
|
|
23
|
-
<div className="loading">Loading Miden WASM...</div>
|
|
24
|
-
}
|
|
25
|
-
>
|
|
26
|
-
{children}
|
|
27
|
-
</MidenProvider>
|
|
28
|
-
</WalletModalProvider>
|
|
29
|
-
</WalletProvider>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
-
"target": "ES2022",
|
|
5
|
-
"useDefineForClassFields": true,
|
|
6
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"types": ["vite/client"],
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
|
|
11
|
-
/* Bundler mode */
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"allowImportingTsExtensions": true,
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"moduleDetection": "force",
|
|
16
|
-
"noEmit": true,
|
|
17
|
-
"jsx": "react-jsx",
|
|
18
|
-
|
|
19
|
-
/* Path aliases */
|
|
20
|
-
"baseUrl": ".",
|
|
21
|
-
"paths": {
|
|
22
|
-
"@/*": ["./src/*"]
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
/* Linting */
|
|
26
|
-
"strict": true,
|
|
27
|
-
"noUnusedLocals": true,
|
|
28
|
-
"noUnusedParameters": true,
|
|
29
|
-
"noFallthroughCasesInSwitch": true
|
|
30
|
-
},
|
|
31
|
-
"include": ["src"]
|
|
32
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
4
|
-
"target": "ES2023",
|
|
5
|
-
"lib": ["ES2023"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"types": ["node"],
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"verbatimModuleSyntax": true,
|
|
14
|
-
"moduleDetection": "force",
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
/* Linting */
|
|
18
|
-
"strict": true,
|
|
19
|
-
"noUnusedLocals": true,
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true
|
|
22
|
-
},
|
|
23
|
-
"include": ["vite.config.ts"]
|
|
24
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { defineConfig } from "vite";
|
|
3
|
-
import react from "@vitejs/plugin-react";
|
|
4
|
-
import { midenVitePlugin } from "@miden-sdk/vite-plugin";
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [react(), midenVitePlugin()],
|
|
8
|
-
resolve: {
|
|
9
|
-
dedupe: ["react", "react-dom", "react/jsx-runtime"],
|
|
10
|
-
alias: {
|
|
11
|
-
"@": path.resolve(__dirname, "./src"),
|
|
12
|
-
// The wallet adapter was published under @demox-labs but imports
|
|
13
|
-
// @demox-labs/miden-sdk internally. Redirect to the current package.
|
|
14
|
-
"@demox-labs/miden-sdk": "@miden-sdk/miden-sdk",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
});
|