├── .npmrc
├── .yarnrc.yml
├── packages
├── ui
│ ├── src
│ │ ├── example.ts
│ │ ├── example.tsx
│ │ ├── example.css
│ │ ├── lib
│ │ │ └── example.ts
│ │ ├── components
│ │ │ └── example.tsx
│ │ ├── hookes
│ │ │ └── example.tsx
│ │ ├── providers
│ │ │ └── example.tsx
│ │ ├── vite-env.d.ts
│ │ ├── assets
│ │ │ └── example.svg
│ │ └── main.tsx
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── .gitignore
│ ├── index.html
│ ├── components.json
│ ├── eslint.config.js
│ ├── tsconfig.node.json
│ ├── tsconfig.app.json
│ ├── vite.config.ts
│ ├── public
│ │ └── vite.svg
│ └── package.json
├── contract
│ ├── src
│ │ ├── index.ts
│ │ └── quick-starter.compact
│ ├── tsconfig.build.json
│ ├── tsconfig.json
│ ├── js-resolver.cjs
│ └── package.json
├── api
│ ├── tsconfig.build.json
│ ├── src
│ │ └── index.ts
│ ├── tsconfig.json
│ └── package.json
└── cli
│ ├── tsconfig.build.json
│ ├── src
│ ├── index.ts
│ ├── common-types.ts
│ ├── launcher
│ │ ├── testnet-remote.ts
│ │ └── standalone.ts
│ ├── logger-utils.ts
│ └── config.ts
│ ├── tsconfig.json
│ ├── js-resolver.cjs
│ ├── fetch-zk-params.sh
│ ├── package.json
│ ├── testnet.yml
│ └── standalone.yml
├── docs
└── README.md
├── compact
├── turbo.json
├── package.json
└── src
│ └── run-compactc.cjs
├── .gitignore
├── SECURITY.md
├── LICENSE
├── turbo.json
├── package.json
└── README.md
/.npmrc:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
--------------------------------------------------------------------------------
/packages/ui/src/example.ts:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure..
--------------------------------------------------------------------------------
/packages/ui/src/example.tsx:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.
--------------------------------------------------------------------------------
/packages/ui/src/example.css:
--------------------------------------------------------------------------------
1 | /*// TODO: Only for folder structure.*/
--------------------------------------------------------------------------------
/packages/ui/src/lib/example.ts:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.
--------------------------------------------------------------------------------
/packages/ui/src/components/example.tsx:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.
--------------------------------------------------------------------------------
/packages/ui/src/hookes/example.tsx:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.
--------------------------------------------------------------------------------
/packages/ui/src/providers/example.tsx:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.
--------------------------------------------------------------------------------
/packages/ui/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/contract/src/index.ts:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure.. Add here your logic.
--------------------------------------------------------------------------------
/packages/ui/src/assets/example.svg:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure. Add your SVG image here.
--------------------------------------------------------------------------------
/packages/api/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["src/test/**/*.ts"],
4 | "compilerOptions": {}
5 | }
6 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["src/**/*.test.ts"],
4 | "compilerOptions": {}
5 | }
6 |
--------------------------------------------------------------------------------
/packages/contract/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["src/test/**/*.ts"],
4 | "compilerOptions": {}
5 | }
6 |
--------------------------------------------------------------------------------
/packages/cli/src/index.ts:
--------------------------------------------------------------------------------
1 | // TODO: Adds all interaction logic between the CLI and the API.
2 | // import {
3 | // QuickStarterPrivateStateId,
4 | // } from "./common-types.js";
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | TODO: Only for structure. Here should be information that refer to the documentation, it can be images, texts, files or folders, feel free to structure the folders as you like.
--------------------------------------------------------------------------------
/packages/ui/src/main.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from "react-dom/client";
2 |
3 | const App = () =>
Hello World!
;
4 |
5 | ReactDOM.createRoot(document.getElementById("root")!).render();
6 |
--------------------------------------------------------------------------------
/packages/contract/src/quick-starter.compact:
--------------------------------------------------------------------------------
1 | pragma language_version >= 0.16.0;
2 |
3 | import CompactStandardLibrary;
4 |
5 | export ledger message: Bytes<12>;
6 |
7 | constructor() {
8 | message = "Hello World!";
9 | }
--------------------------------------------------------------------------------
/packages/api/src/index.ts:
--------------------------------------------------------------------------------
1 | // TODO: Only for folder structure. Adjust QuickStarterPrivateStateId based on your implementation.
2 | // Common types and constants
3 | export const QuickStarterPrivateStateId = 'quick-starter-private-state';
--------------------------------------------------------------------------------
/packages/ui/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
--------------------------------------------------------------------------------
/compact/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "extends": ["//"],
4 | "tasks": {
5 | "build": {
6 | "outputs": ["compact/**"],
7 | "env": ["COMPACT_HOME"],
8 | "inputs": ["src/**"],
9 | "cache": true
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ],
7 | "compilerOptions": {
8 | "baseUrl": ".",
9 | "paths": {
10 | "@/*": ["./src/*"]
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/cli/src/common-types.ts:
--------------------------------------------------------------------------------
1 | import { MidnightProviders } from "@midnight-ntwrk/midnight-js-types";
2 |
3 | export const QuickStarterPrivateStateId = "quickStarterPrivateState";
4 | export type QuickStarterPrivateStateId = typeof QuickStarterPrivateStateId;
5 | export type QuickStarterContractProviders = MidnightProviders<
6 | QuickStarterPrivateStateId
7 | >;
8 |
--------------------------------------------------------------------------------
/packages/ui/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 | .vercel
26 |
--------------------------------------------------------------------------------
/packages/ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Midnight Quick Starter
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/cli/src/launcher/testnet-remote.ts:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | TODO: Tesnet config - you can use this or continue following similar implementation
4 |
5 | import { createLogger } from '../logger-utils.js';
6 | import { run } from '../index.js';
7 | import { TestnetRemoteConfig } from '../config.js';
8 |
9 | const config = new TestnetRemoteConfig();
10 | config.setNetworkId();
11 | const logger = await createLogger(config.logDir);
12 | await run(config, logger);
13 | */
--------------------------------------------------------------------------------
/compact/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@quick-starter/quick-starter-compact",
3 | "description": "Compact fetcher",
4 | "author": "IOG",
5 | "license": "Apache-2.0",
6 | "private": true,
7 | "version": "0.1.0",
8 | "type": "module",
9 | "packageManager": "yarn@4.0.0",
10 | "bin": {
11 | "run-compact": "src/run-compact.cjs"
12 | },
13 | "devDependencies": {
14 | "eslint": "^8.52.0",
15 | "ts-node": "^10.9.2",
16 | "typescript": "^5.2.2"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/ui/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": false,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "",
8 | "css": "src/index.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils",
16 | "ui": "@/components/ui",
17 | "lib": "@/lib",
18 | "hooks": "@/hooks"
19 | },
20 | "iconLibrary": "lucide"
21 | }
--------------------------------------------------------------------------------
/packages/contract/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*.ts"],
3 | "compilerOptions": {
4 | "rootDir": "src",
5 | "outDir": "dist",
6 | "declaration": true,
7 | "lib": ["ESNext"],
8 | "target": "ES2022",
9 | "module": "ESNext",
10 | "moduleResolution": "node",
11 | "allowJs": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "noImplicitAny": true,
14 | "strict": true,
15 | "isolatedModules": true,
16 | "sourceMap": true,
17 | "resolveJsonModule": true,
18 | "esModuleInterop": true,
19 | "skipLibCheck": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/cli/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*.ts"],
3 | "compilerOptions": {
4 | // "rootDir": "src",
5 | "outDir": "dist",
6 | "declaration": true,
7 | "lib": ["ESNext"],
8 | "target": "ES2022",
9 | "module": "ESNext",
10 | "moduleResolution": "node",
11 | "allowJs": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "noImplicitAny": true,
14 | "strict": true,
15 | "isolatedModules": true,
16 | "sourceMap": true,
17 | "resolveJsonModule": true,
18 | "esModuleInterop": true,
19 | "skipLibCheck": true,
20 | "baseUrl": "."
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/packages/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*.ts", "src/test/jest.setup.ts"],
3 | "compilerOptions": {
4 | "rootDir": "src",
5 | "outDir": "dist",
6 | "declaration": true,
7 | "lib": ["ESNext", "DOM"],
8 | "target": "ES2022",
9 | "module": "NodeNext",
10 | "moduleResolution": "nodenext",
11 | "allowJs": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "noImplicitAny": true,
14 | "strict": true,
15 | "isolatedModules": true,
16 | "sourceMap": true,
17 | "resolveJsonModule": true,
18 | "esModuleInterop": true,
19 | "skipLibCheck": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | managed
6 | logs
7 | midnight-level-db
8 | .pnp
9 | .pnp.js
10 |
11 | # Local env files
12 | .env
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | # Testing
19 | coverage
20 |
21 | # Turbo
22 | .turbo
23 |
24 | # Vercel
25 | .vercel
26 |
27 | # Build Outputs
28 | .next/
29 | out/
30 | build
31 | dist
32 | .cache
33 | .yarn/*
34 |
35 | # Debug
36 | npm-debug.log*
37 | yarn-debug.log*
38 | yarn-error.log*
39 |
40 | # Misc
41 | .DS_Store
42 | *.pem
43 |
--------------------------------------------------------------------------------
/packages/cli/js-resolver.cjs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ---
4 | TODO: Use this resolver to work correctly with node_modules in each workspace.
5 | ---
6 |
7 | const jsResolver = (path, options) => {
8 | const jsExtRegex = /\.js$/i
9 | const resolver = options.defaultResolver
10 | if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) {
11 | const newPath = path.replace(jsExtRegex, '.ts');
12 | try {
13 | return resolver(newPath, options)
14 | } catch {
15 | // use default resolver
16 | }
17 | }
18 |
19 | return resolver(path, options)
20 | }
21 |
22 | module.exports = jsResolver
23 | */
--------------------------------------------------------------------------------
/packages/contract/js-resolver.cjs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ---
4 | TODO: Use this resolver to work correctly with node_modules in all workspaces.
5 | ---
6 |
7 | const jsResolver = (path, options) => {
8 | const jsExtRegex = /\.js$/i
9 | const resolver = options.defaultResolver
10 | if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) {
11 | const newPath = path.replace(jsExtRegex, '.ts');
12 | try {
13 | return resolver(newPath, options)
14 | } catch {
15 | // use default resolver
16 | }
17 | }
18 |
19 | return resolver(path, options)
20 | }
21 |
22 | module.exports = jsResolver
23 | */
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | Security vulnerabilities should be disclosed to the project maintainers by email to .
4 |
5 | ## Legal
6 |
7 | Blockchain is a nascent technology and carries a high level of risk and uncertainty. I makes certain software available under open source licenses that disclaim all warranties related to the project and limit the liability of I. You are solely responsible for your use of the project and assume all risks associated with such use. This Security Policy does not represent or imply any ongoing duty by any contributor, including I, to fix issues or vulnerabilities, or to notify you of any or all risks related to the use of the project.
--------------------------------------------------------------------------------
/packages/ui/eslint.config.js:
--------------------------------------------------------------------------------
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 { globalIgnores } from 'eslint/config'
7 |
8 | export default tseslint.config([
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 | ])
24 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4 | "target": "ES2023",
5 | "lib": ["ES2023"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "verbatimModuleSyntax": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "erasableSyntaxOnly": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "noUncheckedSideEffectImports": true
23 | },
24 | "include": ["vite.config.ts"]
25 | }
26 |
--------------------------------------------------------------------------------
/packages/cli/src/launcher/standalone.ts:
--------------------------------------------------------------------------------
1 | /*
2 | ---
3 | TODO: Standalone config - you can use this or continue following similar implementation
4 | ---
5 |
6 | import { createLogger } from '../logger-utils.js';
7 | import path from 'node:path';
8 | import { run } from '../index.js';
9 | import { DockerComposeEnvironment, Wait } from 'testcontainers';
10 | import { currentDir, StandaloneConfig } from '../config.js';
11 |
12 | const config = new StandaloneConfig();
13 | config.setNetworkId();
14 | const dockerEnv = new DockerComposeEnvironment(path.resolve(currentDir, '..'), 'standalone.yml')
15 | .withWaitStrategy('proof-server', Wait.forLogMessage('Actix runtime found; starting in Actix runtime', 1))
16 | .withWaitStrategy('graphql-api', Wait.forLogMessage(/Transactions subscription started/, 1));
17 | const logger = await createLogger(config.logDir);
18 | await run(config, logger, dockerEnv);
19 | */
--------------------------------------------------------------------------------
/packages/ui/tsconfig.app.json:
--------------------------------------------------------------------------------
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 | "skipLibCheck": true,
9 | "baseUrl": ".",
10 | "paths": {
11 | "@/*": ["./src/*"]
12 | },
13 |
14 | /* Bundler mode */
15 | "moduleResolution": "bundler",
16 | "allowImportingTsExtensions": true,
17 | "verbatimModuleSyntax": true,
18 | "moduleDetection": "force",
19 | "noEmit": true,
20 | "jsx": "react-jsx",
21 |
22 | /* Linting */
23 | "strict": true,
24 | "noUnusedLocals": true,
25 | "noUnusedParameters": true,
26 | "erasableSyntaxOnly": true,
27 | "noFallthroughCasesInSwitch": true,
28 | "noUncheckedSideEffectImports": true
29 | },
30 | "include": ["src", "example.ts", "example.tsx"]
31 | }
32 |
--------------------------------------------------------------------------------
/packages/cli/src/logger-utils.ts:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | ---
4 | TODO: Only for structure. Use this debbug level to see all detailed logs.
5 | ---
6 |
7 | import * as path from 'node:path';
8 | import * as fs from 'node:fs/promises';
9 | import pinoPretty from 'pino-pretty';
10 | import pino from 'pino';
11 | import { createWriteStream } from 'node:fs';
12 |
13 | export const createLogger = async (logPath: string): Promise => {
14 | await fs.mkdir(path.dirname(logPath), { recursive: true });
15 | const pretty: pinoPretty.PrettyStream = pinoPretty({
16 | colorize: true,
17 | sync: true,
18 | });
19 | const level =
20 | process.env.DEBUG_LEVEL !== undefined && process.env.DEBUG_LEVEL !== null && process.env.DEBUG_LEVEL !== ''
21 | ? process.env.DEBUG_LEVEL
22 | : 'info';
23 | return pino(
24 | {
25 | level,
26 | depthLimit: 20,
27 | },
28 | pino.multistream([
29 | { stream: pretty, level },
30 | { stream: createWriteStream(logPath), level },
31 | ]),
32 | );
33 | };
34 | */
--------------------------------------------------------------------------------
/packages/cli/fetch-zk-params.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Copyright 2025 Brick Towers
3 |
4 | set -e # exit on error
5 | set -x # print each command before executing
6 |
7 | # Default CIRCUIT_PARAM_RANGE if not provided
8 | CIRCUIT_PARAM_RANGE=${CIRCUIT_PARAM_RANGE:-"10 11 12 13 14 15 16 17"}
9 | ZK_PARAMS_DIR=${ZK_PARAMS_DIR:-".cache/midnight/zk-params"}
10 |
11 | # Create target directory
12 | mkdir -p "$ZK_PARAMS_DIR/zswap/4"
13 |
14 | echo "📥 Downloading BLS Filecoin params..."
15 | for i in $CIRCUIT_PARAM_RANGE; do
16 | echo " ↳ bls_filecoin_2p$i"
17 | curl -sSLo "$ZK_PARAMS_DIR/bls_filecoin_2p$i" \
18 | "https://midnight-s3-fileshare-dev-eu-west-1.s3.eu-west-1.amazonaws.com/bls_filecoin_2p$i"
19 | done
20 |
21 | echo "📥 Downloading zswap/4 circuits..."
22 | cd "$ZK_PARAMS_DIR/zswap/4" || exit 1
23 | for file in \
24 | output.bzkir output.prover output.verifier \
25 | sign.bzkir sign.prover sign.verifier \
26 | spend.bzkir spend.prover spend.verifier; do
27 | echo " ↳ $file"
28 | curl -sSLO "https://midnight-s3-fileshare-dev-eu-west-1.s3.eu-west-1.amazonaws.com/zswap/4/$file"
29 | done
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 luislucena16
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/compact/src/run-compactc.cjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /*
4 | Search for the compact compiler on your operating system
5 | */
6 |
7 | const childProcess = require('child_process');
8 | const path = require('path');
9 |
10 | const [_node, _script, ...args] = process.argv;
11 | const COMPACT_HOME_ENV = process.env.COMPACT_HOME;
12 |
13 | let compactPath;
14 | if (COMPACT_HOME_ENV != null) {
15 | compactPath = COMPACT_HOME_ENV;
16 | console.log(`COMPACT_HOME env variable is set; using Compact from ${compactPath}`);
17 | } else {
18 | compactPath = path.resolve(__dirname, '..', 'compact');
19 | console.log(`COMPACT_HOME env variable is not set; using fetched compact from ${compactPath}`);
20 | }
21 |
22 | // Debug: Print the full path to compact and zkir
23 | console.log(`compact path: ${path.resolve(compactPath, 'compact')}`);
24 | console.log(`zkir path: ${path.resolve(compactPath, 'zkir')}`);
25 |
26 | // yarn runs everything with node...
27 | const child = childProcess.spawn(path.resolve(compactPath, 'compact'), args, {
28 | stdio: 'inherit'
29 | });
30 | child.on('exit', (code, signal) => {
31 | if (code === 0) {
32 | process.exit(0);
33 | } else {
34 | process.exit(code ?? signal);
35 | }
36 | });
--------------------------------------------------------------------------------
/packages/cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@quick-starter/quick-starter-cli",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "type": "module",
7 | "packageManager": "yarn@4.9.2",
8 | "scripts": {
9 | "testnet-remote": "node --loader ts-node/esm --experimental-specifier-resolution=node dist/launcher/testnet-remote.js",
10 | "standalone": "node --experimental-specifier-resolution=node dist/launcher/standalone.js",
11 | "test": "yarn test-e2e",
12 | "test-e2e": "NODE_OPTIONS=--experimental-vm-modules jest --detectOpenHandles --forceExit",
13 | "build": "rm -rf dist && tsc --project tsconfig.build.json",
14 | "lint": "eslint src"
15 | },
16 | "dependencies": {
17 | "@quick-starter/quick-starter-api": "workspace:*",
18 | "@quick-starter/quick-starter-contract": "workspace:*",
19 | "pino": "^8.16.1",
20 | "ws": "^8.14.2"
21 | },
22 | "devDependencies": {
23 | "@types/jest": "^29.5.12",
24 | "@types/ws": "^8.5.9",
25 | "allure-commandline": "^2.32.0",
26 | "allure-jest": "^3.0.5",
27 | "allure-js-commons": "^3.0.5",
28 | "eslint": "^8.52.0",
29 | "jest": "^29.7.0",
30 | "ts-jest": "^29.1.2",
31 | "typescript": "^5.2.2"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/contract/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@quick-starter/quick-starter-contract",
3 | "version": "0.1.0",
4 | "license": "MIT",
5 | "type": "module",
6 | "main": "index.js",
7 | "module": "./dist/index.js",
8 | "types": "./dist/index.d.ts",
9 | "packageManager": "yarn@4.9.2",
10 | "exports": {
11 | ".": {
12 | "default": "./dist/index.js",
13 | "import": "./dist/index.js",
14 | "types": "./dist/index.d.ts",
15 | "require": "./dist/index.js"
16 | }
17 | },
18 | "scripts": {
19 | "compact": "compact compile src/quick-starter.compact ./src/managed/quick-starter",
20 | "build": "rm -rf dist && find src/managed -type d -empty -delete && tsc --project tsconfig.build.json && mkdir -p dist/managed && test -d ./src/managed/quick-starter && cp -R ./src/managed/quick-starter ./dist/managed/ && mkdir -p ./dist/managed/quick-starter/keys ./dist/managed/quick-starter/zkir && cp ./src/*.compact dist",
21 | "lint": "eslint src",
22 | "typecheck": "tsc -p tsconfig.json --noEmit",
23 | "prepack": "yarn build"
24 | },
25 | "devDependencies": {
26 | "@quick-starter/quick-starter-compact": "workspace:*",
27 | "eslint": "^9.27.0",
28 | "jest": "^29.7.0",
29 | "typescript": "^5.8.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/ui/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react";
3 | import tailwindcss from "@tailwindcss/vite";
4 | import path from "path";
5 | import { viteCommonjs } from "@originjs/vite-plugin-commonjs";
6 | import wasm from "vite-plugin-wasm";
7 | import topLevelAwait from "vite-plugin-top-level-await";
8 |
9 | // https://vite.dev/config/
10 | export default defineConfig({
11 | cacheDir: "./.vite",
12 | build: {
13 | target: "esnext",
14 | minify: false,
15 | },
16 | plugins: [react(), tailwindcss(), wasm(), topLevelAwait(), viteCommonjs()],
17 | resolve: {
18 | alias: {
19 | "@": path.resolve(__dirname, "./src"),
20 | buffer: 'buffer',
21 | process: 'process/browser',
22 | util: 'util',
23 | crypto: 'crypto-browserify',
24 | stream: 'stream-browserify',
25 | assert: 'assert',
26 | http: 'stream-http',
27 | https: 'https-browserify',
28 | os: 'os-browserify',
29 | url: 'url',
30 | fs: 'browserify-fs',
31 | },
32 |
33 | },
34 | optimizeDeps: {
35 | esbuildOptions: {
36 | target: "esnext",
37 | },
38 | include: [
39 | 'buffer',
40 | 'process',
41 | ],
42 | },
43 | define: {},
44 | });
45 |
--------------------------------------------------------------------------------
/packages/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@quick-starter/quick-starter-api",
3 | "packageManager": "yarn@4.9.2",
4 | "type": "module",
5 | "main": "./dist/index.js",
6 | "module": "./dist/index.js",
7 | "types": "./dist/index.d.ts",
8 | "private": true,
9 | "license": "MIT",
10 | "exports": {
11 | ".": {
12 | "import": "./dist/index.js",
13 | "require": "./dist/index.js",
14 | "types": "./dist/index.d.ts"
15 | }
16 | },
17 | "scripts": {
18 | "lint": "eslint src",
19 | "prepare-local-env": "RUN_STANDALONE='true' NODE_OPTIONS=--experimental-vm-modules jest -t 'prepare local env' --detectOpenHandles --forceExit",
20 | "test-api": "DEBUG='testcontainers' NODE_OPTIONS=--experimental-vm-modules jest --detectOpenHandles --forceExit",
21 | "build": "rm -rf dist && tsc --project tsconfig.build.json"
22 | },
23 | "dependencies": {
24 | "@quick-starter/quick-starter-contract": "workspace:*",
25 | "pino": "^8.16.1",
26 | "uuid": "^11.1.0",
27 | "ws": "8.17.1"
28 | },
29 | "devDependencies": {
30 | "@types/ws": "^8.5.9",
31 | "allure-commandline": "^2.28.0",
32 | "allure-jest": "^2.15.1",
33 | "allure-js-commons": "^2.15.1",
34 | "eslint": "^8.52.0",
35 | "jest": "^29.7.0",
36 | "typescript": "^5.8.3"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/ui/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/cli/testnet.yml:
--------------------------------------------------------------------------------
1 | services:
2 | proof-server:
3 | container_name: 'quick-starter-proof-server'
4 | image: 'midnightnetwork/proof-server:4.0.0'
5 | entrypoint: ['midnight-proof-server', '--network', 'testnet', '--verbose']
6 | ports:
7 | - "6300:6300"
8 | volumes:
9 | - ${PWD}/.cache/midnight/zk-params:/.cache/midnight/zk-params
10 | environment:
11 | RUST_BACKTRACE: "full"
12 | RUST_LOG: "trace,actix_web::middleware::logger=trace,actix_web=trace"
13 | indexer:
14 | container_name: 'quick-starter-indexer'
15 | image: 'midnightntwrk/indexer-standalone:2.1.1-rc.1-99b0bce4'
16 | platform: linux/amd64
17 | ports:
18 | - '8088:8088'
19 | environment:
20 | RUST_LOG: "indexer=info,chain_indexer=info,indexer_api=info,wallet_indexer=info,indexer_common=info,fastrace_opentelemetry=off,info"
21 | # Random 32-byte hex-encoded secret used to make the standalone indexer run.
22 | # Only needed to satisfy the config schema – not meant for secure use.
23 | APP__INFRA__SECRET: "303132333435363738393031323334353637383930313233343536373839303132"
24 | APP__INFRA__NODE__URL: "ws://node:9944"
25 | depends_on:
26 | node:
27 | condition: service_started
28 | node:
29 | image: 'midnightnetwork/midnight-node:0.12.0'
30 | platform: linux/amd64
31 | container_name: 'quick-starter-node'
32 | ports:
33 | - "9944:9944"
34 | healthcheck:
35 | test: [ "CMD", "curl", "-f", "http://localhost:9944/health" ]
36 | interval: 2s
37 | timeout: 5s
38 | retries: 5
39 | start_period: 40s
40 | environment:
41 | CFG_PRESET: "dev"
--------------------------------------------------------------------------------
/packages/cli/standalone.yml:
--------------------------------------------------------------------------------
1 | services:
2 | proof-server:
3 | container_name: 'quick-starter-proof-server'
4 | image: 'midnightnetwork/proof-server:4.0.0'
5 | entrypoint: ['midnight-proof-server', '--network', 'undeployed', '--verbose']
6 | ports:
7 | - "6300:6300"
8 | volumes:
9 | - ${PWD}/.cache/midnight/zk-params:/.cache/midnight/zk-params
10 | environment:
11 | RUST_BACKTRACE: "full"
12 | RUST_LOG: "trace,actix_web::middleware::logger=trace,actix_web=trace"
13 | indexer:
14 | container_name: 'quick-starter-indexer'
15 | image: 'midnightntwrk/indexer-standalone:2.1.1-rc.1-99b0bce4'
16 | platform: linux/amd64
17 | ports:
18 | - '8088:8088'
19 | environment:
20 | RUST_LOG: "indexer=info,chain_indexer=info,indexer_api=info,wallet_indexer=info,indexer_common=info,fastrace_opentelemetry=off,info"
21 | # Random 32-byte hex-encoded secret used to make the standalone indexer run.
22 | # Only needed to satisfy the config schema – not meant for secure use.
23 | APP__INFRA__SECRET: "303132333435363738393031323334353637383930313233343536373839303132"
24 | APP__INFRA__NODE__URL: "ws://node:9944"
25 | depends_on:
26 | node:
27 | condition: service_started
28 | node:
29 | image: 'midnightnetwork/midnight-node:0.12.0'
30 | platform: linux/amd64
31 | container_name: 'quick-starter-node'
32 | ports:
33 | - "9944:9944"
34 | healthcheck:
35 | test: [ "CMD", "curl", "-f", "http://localhost:9944/health" ]
36 | interval: 2s
37 | timeout: 5s
38 | retries: 5
39 | start_period: 40s
40 | environment:
41 | CFG_PRESET: "dev"
--------------------------------------------------------------------------------
/packages/cli/src/config.ts:
--------------------------------------------------------------------------------
1 |
2 | import path from 'node:path';
3 | import { NetworkId, setNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
4 | import { QuickStarterPrivateStateId } from '@quick-starter/quick-starter-api';
5 |
6 | export interface Config {
7 | readonly privateStateStoreName: string;
8 | readonly logDir: string;
9 | readonly zkConfigPath: string;
10 | readonly indexer: string;
11 | readonly indexerWS: string;
12 | readonly node: string;
13 | readonly proofServer: string;
14 |
15 | setNetworkId: () => void;
16 | }
17 |
18 | export const currentDir = path.resolve(new URL(import.meta.url).pathname, '..');
19 |
20 | export class StandaloneConfig implements Config {
21 | privateStateStoreName = QuickStarterPrivateStateId
22 | logDir = path.resolve(currentDir, '..', 'logs', 'standalone', `${new Date().toISOString()}.log`);
23 | zkConfigPath = path.resolve(currentDir, '..', '..', 'contract', 'dist', 'managed', 'quick-starter');
24 | indexer = 'http://127.0.0.1:8088/api/v1/graphql';
25 | indexerWS = 'ws://127.0.0.1:8088/api/v1/graphql/ws';
26 | node = 'http://127.0.0.1:9944';
27 | proofServer = 'http://127.0.0.1:6300';
28 |
29 | setNetworkId() {
30 | setNetworkId(NetworkId.Undeployed);
31 | }
32 | }
33 |
34 | export class TestnetRemoteConfig implements Config {
35 | privateStateStoreName = QuickStarterPrivateStateId
36 | logDir = path.resolve(currentDir, '..', 'logs', 'testnet-remote', `${new Date().toISOString()}.log`);
37 | zkConfigPath = path.resolve(currentDir, '..', '..', 'contract', 'dist', 'managed', 'quick-starter');
38 | indexer = 'https://indexer-rs.testnet-02.midnight.network/api/v1/graphql';
39 | indexerWS = 'wss://indexer-rs.testnet-02.midnight.network/api/v1/graphql/ws';
40 | node = 'https://rpc.testnet-02.midnight.network';
41 | proofServer = 'https://lace-dev.proof-pub.stg.midnight.tools';
42 |
43 | setNetworkId() {
44 | setNetworkId(NetworkId.TestNet);
45 | }
46 | }
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": [
4 | ".prettierrc.json"
5 | ],
6 | "tasks": {
7 | "typecheck": {
8 | "dependsOn": ["^build", "compact"],
9 | "inputs": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.mts", "tsconfig.json"],
10 | "outputs": []
11 | },
12 | "compact": {
13 | "dependsOn": ["^build"],
14 | "env": ["COMPACT_HOME"],
15 | "inputs": ["src/**/*.compact"],
16 | "outputs": ["src/managed/**", "src/gen/**", "gen/**"]
17 | },
18 | "build": {
19 | "dependsOn": ["^build", "compact", "typecheck"],
20 | "inputs": ["src/**/*.ts", "src/**/*.mts", "src/**/*.tsx", "!src/**/*.test.ts", "!tests/**/*.ts", "tsconfig.json", "tsconfig.build.json", ".env"],
21 | "outputs": ["dist/**"]
22 | },
23 | "build-storybook": {
24 | "dependsOn": ["^build", "typecheck"],
25 | "inputs": ["src/**/*.ts", "src/**/*.mts", "src/**/*.tsx", "!src/**/*.test.ts", "!tests/**/*.ts", "tsconfig.json", "tsconfig.build.json", ".env", "vite.config.ts", ".storybook/**"],
26 | "outputs": ["storybook-static/**"]
27 | },
28 | "lint": {
29 | "dependsOn": ["compact", "^build", "typecheck"],
30 | "inputs": ["src/**/*.ts", "src/**/*.mts", "src/**/*.tsx", ".eslintrc.cjs"]
31 | },
32 | "test": {
33 | "dependsOn": ["^build", "compact", "typecheck"],
34 | "inputs": ["src/**/*.ts", "src/**/*.mts", "src/**/*.tsx", "jest.config.ts", "tsconfig.json", "tsconfig.test.json", "test-compose.yml"],
35 | "outputs": ["reports/**"]
36 | },
37 | "check": {
38 | "dependsOn": ["build", "lint", "test", "build-storybook"]
39 | },
40 | "test-e2e": {
41 | "dependsOn": ["build", "compact"]
42 | },
43 | "start": {
44 | "cache": false,
45 | "persistent": true,
46 | "dependsOn": ["build"]
47 | },
48 | "dev": {
49 | "cache": false,
50 | "persistent": true
51 | },
52 | "storybook": {
53 | "cache": false,
54 | "persistent": true,
55 | "dependsOn": ["build"]
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/packages/ui/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "quick-starter-ui",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "start": "http-server --port 0 ./dist",
9 | "build": "tsc && vite build --mode testnet && cp -r ../contract/dist/managed/quick-starter/keys ./dist/keys && cp -r ../contract/dist/managed/quick-starter/zkir ./dist/zkir",
10 | "lint": "eslint .",
11 | "preview": "vite preview"
12 | },
13 | "dependencies": {
14 | "@quick-starter/quick-starter-api": "workspace:*",
15 | "@quick-starter/quick-starter-contract": "workspace:*",
16 | "@radix-ui/react-dialog": "^1.1.14",
17 | "@radix-ui/react-label": "^2.1.7",
18 | "@radix-ui/react-progress": "^1.1.7",
19 | "@radix-ui/react-slot": "^1.2.3",
20 | "@tailwindcss/vite": "^4.1.11",
21 | "badge": "^1.0.3",
22 | "button": "^1.1.1",
23 | "card": "^2.5.4",
24 | "class-variance-authority": "^0.7.1",
25 | "clsx": "^2.1.1",
26 | "dialog": "^0.3.1",
27 | "http-server": "^14.1.1",
28 | "init": "^0.1.2",
29 | "input": "^1.0.1",
30 | "label": "^0.2.2",
31 | "lucide-react": "^0.523.0",
32 | "progress": "^2.0.3",
33 | "react": "^19.1.0",
34 | "react-dom": "^19.1.0",
35 | "react-hot-toast": "^2.5.2",
36 | "shadcn": "^2.7.0",
37 | "tailwind-merge": "^3.3.1",
38 | "tailwindcss": "^4.1.11",
39 | "textarea": "^0.3.0",
40 | "uuid": "^11.1.0"
41 | },
42 | "devDependencies": {
43 | "@eslint/js": "^9.29.0",
44 | "@originjs/vite-plugin-commonjs": "^1.0.3",
45 | "@types/node": "^24.0.4",
46 | "@types/progress": "^2",
47 | "@types/react": "^19.1.8",
48 | "@types/react-dom": "^19.1.6",
49 | "@vitejs/plugin-react": "^4.5.2",
50 | "assert": "^2.0.0",
51 | "browserify-fs": "^1.0.0",
52 | "buffer": "^6.0.3",
53 | "crypto-browserify": "^3.12.0",
54 | "eslint": "^9.29.0",
55 | "eslint-plugin-react-hooks": "^5.2.0",
56 | "eslint-plugin-react-refresh": "^0.4.20",
57 | "globals": "^16.2.0",
58 | "https-browserify": "^1.0.0",
59 | "os-browserify": "^0.3.0",
60 | "process": "^0.11.10",
61 | "stream-browserify": "^3.0.0",
62 | "stream-http": "^3.2.0",
63 | "tw-animate-css": "^1.3.4",
64 | "typescript": "~5.8.3",
65 | "typescript-eslint": "^8.34.1",
66 | "url": "^0.11.0",
67 | "util": "^0.12.5",
68 | "vite": "^7.0.0",
69 | "vite-plugin-top-level-await": "^1.5.0",
70 | "vite-plugin-wasm": "^3.4.1"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "midnight-quick-starter",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "build": "turbo run build",
7 | "build:all": "cd packages/contract && npx turbo run build && cd ../api && npx turbo run build && cd ../cli && npx turbo run build && cd ../ui && npx turbo run build",
8 | "clean": "turbo run clean",
9 | "clean:cache": "rm -rf .turbo && rm -rf node_modules/.cache"
10 | },
11 | "private": true,
12 | "resolutions": {
13 | "@midnight-ntwrk/compact-runtime/@midnight-ntwrk/onchain-runtime": "^0.3.0",
14 | "@midnight-ntwrk/zswap": "4.0.0"
15 | },
16 | "dependencies": {
17 | "@midnight-ntwrk/compact-runtime": "^0.8.1",
18 | "@midnight-ntwrk/dapp-connector-api": "3.0.0",
19 | "@midnight-ntwrk/ledger": "^4.0.0",
20 | "@midnight-ntwrk/midnight-js-contracts": "2.0.2",
21 | "@midnight-ntwrk/midnight-js-fetch-zk-config-provider": "2.0.2",
22 | "@midnight-ntwrk/midnight-js-http-client-proof-provider": "^2.0.2",
23 | "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "2.0.2",
24 | "@midnight-ntwrk/midnight-js-level-private-state-provider": "2.0.2",
25 | "@midnight-ntwrk/midnight-js-network-id": "2.0.2",
26 | "@midnight-ntwrk/midnight-js-node-zk-config-provider": "2.0.2",
27 | "@midnight-ntwrk/midnight-js-types": "2.0.2",
28 | "@midnight-ntwrk/midnight-js-utils": "2.0.2",
29 | "@midnight-ntwrk/wallet": "5.0.0",
30 | "@midnight-ntwrk/wallet-api": "^5.0.0",
31 | "@midnight-ntwrk/wallet-sdk-address-format": "2.0.0",
32 | "fp-ts": "^2.16.1",
33 | "io-ts": "^2.2.20",
34 | "pino": "^9.7.0",
35 | "pino-pretty": "^13.0.0",
36 | "rxjs": "^7.8.1",
37 | "ws": "^8.18.1"
38 | },
39 | "devDependencies": {
40 | "@types/jest": "^29.5.6",
41 | "@types/node": "^22.15.21",
42 | "@types/ws": "^8.18.1",
43 | "@typescript-eslint/eslint-plugin": "^6.8.0",
44 | "@typescript-eslint/parser": "^8.32.1",
45 | "eslint": "^9.26.0",
46 | "eslint-config-prettier": "^10.1.0",
47 | "eslint-plugin-import": "^2.28.1",
48 | "eslint-plugin-n": "^16.2.0",
49 | "eslint-plugin-prettier": "^5.4.0",
50 | "eslint-plugin-promise": "^6.1.1",
51 | "fast-check": "^3.15.0",
52 | "jest": "^29.7.0",
53 | "jest-fast-check": "^2.0.0",
54 | "jest-gh-md-reporter": "^0.0.2",
55 | "jest-html-reporters": "^3.1.4",
56 | "jest-junit": "^16.0.0",
57 | "prettier": "^3.0.3",
58 | "testcontainers": "^10.27.0",
59 | "ts-jest": "^29.1.1",
60 | "ts-node": "^10.9.2",
61 | "turbo": "2.5.5",
62 | "typescript": "^5.8.3"
63 | },
64 | "engines": {
65 | "node": ">=22"
66 | },
67 | "packageManager": "yarn@4.9.2",
68 | "workspaces": [
69 | "compact",
70 | "packages/ui",
71 | "packages/api",
72 | "packages/cli",
73 | "packages/contract"
74 | ]
75 | }
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌙 Midnight Quick Starter Template
2 |
3 | > **Base template for blockchain projects on Midnight Network** - A complete and modern template for developing decentralized applications (dApps) with smart contracts, backend APIs, CLI tools, and user interfaces.
4 |
5 | ## 📋 Table of Contents
6 |
7 | - [🎯 Description](#-description)
8 | - [✨ Features](#-features)
9 | - [🏗️ Architecture](#️-architecture)
10 | - [⚙️ System Requirements](#️-system-requirements)
11 | - [🚀 Installation](#-installation)
12 | - [📖 Basic Usage](#-basic-usage)
13 | - [🏛️ Project Structure](#️-project-structure)
14 | - [🔍 Quick Development Guide](#-quick-development-guide)
15 | - [🐳 Docker Services](#-docker-services)
16 | - [🚀 Running the Application](#-running-the-application)
17 | - [🤝 Contributing](#-contributing)
18 | - [📄 License](#-license)
19 | - [🚀 Roadmap & Ideas for Improvement](#-roadmap-ideas-for-improvement)
20 |
21 | ## 🎯 Description
22 |
23 | **Midnight Quick Starter** is a complete and modern template for developing blockchain applications on the Midnight network. This template provides a solid foundation with all the necessary tools to create dApps with smart contracts, APIs, user interfaces, and CLI tools.
24 |
25 | ### Use Cases
26 |
27 | - ✅ Complete dApp development on Midnight Network
28 | - ✅ Smart contract creation with Compact
29 | - ✅ Backend APIs for blockchain interaction
30 | - ✅ Modern user interfaces with React
31 | - ✅ CLI tools for development
32 | - ✅ Monorepo with optimized dependency management
33 |
34 | ## ✨ Features
35 |
36 | - **🔧 Monorepo with Turbo** - Optimized build system and dependency management
37 | - **📝 TypeScript** - Complete static typing across all packages
38 | - **⚡ React + Vite** - Modern UI with hot reload
39 | - **🔒 Compact Contracts** - Smart contracts with Compact language
40 | - **🌐 REST/WebSocket API** - Backend for blockchain interaction
41 | - **🖥️ CLI Tools** - Command line tools
42 | - **🎨 Tailwind CSS** - Modern and responsive styles
43 | - **📏 ESLint + Prettier** - Clean and consistent code
44 |
45 | ## 🏗️ Architecture
46 |
47 | ```
48 | midnight-quick-starter/
49 | ├── 📦 packages/
50 | │ ├── 🎨 ui/ # React + Vite Frontend
51 | │ ├── 🔧 api/ # Backend API
52 | │ ├── 🖥️ cli/ # CLI Tools
53 | │ └── 🔒 contract/ # Compact Contracts
54 | ├── 🔧 compact/ # Compact Compiler
55 | └── 📚 docs/ # Documentation
56 | ```
57 |
58 | ## ⚙️ System Requirements
59 |
60 | - **Node.js** >= 22.0.0
61 | - **Yarn** >= 4.9.2
62 | - **Git** >= 2.0.0
63 | - **Docker** (optional, for local testing)
64 |
65 | ### Requirements Verification
66 |
67 | ```bash
68 | node --version # >= 22.0.0
69 | yarn --version # >= 4.9.2
70 | git --version # >= 2.0.0
71 | ```
72 |
73 | ## 🚀 Installation
74 |
75 | ### 1. Clone the Template
76 |
77 | ```bash
78 | # Option 1: Use "Use this template" button on GitHub
79 | # Click "Use this template" → "Create a new repository"
80 |
81 | # Option 2: Fork the repository
82 | # Click "Fork" → Clone your forked repository
83 | git clone
84 | cd midnight-quick-starter
85 |
86 | # Option 3: Clone directly (for contributing)
87 | git clone
88 | cd midnight-quick-starter
89 | ```
90 |
91 | ### 2. Install Dependencies
92 |
93 | ```bash
94 | yarn install
95 | ```
96 |
97 | ### 3. Download and Prepare ZK Parameters (Required for Proofs)
98 |
99 | Before building, you need to fetch the zero-knowledge (ZK) parameters required by the proof server. This is done via a helper script that you should place in the CLI package:
100 |
101 | ```bash
102 | # Move to the CLI package directory
103 | cd packages/cli
104 |
105 | # Download the fetch-zk-params.sh script
106 | curl -O https://raw.githubusercontent.com/bricktowers/midnight-proof-server/main/fetch-zk-params.sh
107 | # or
108 | wget https://raw.githubusercontent.com/bricktowers/midnight-proof-server/main/fetch-zk-params.sh
109 |
110 | # Give execution permissions
111 | chmod +x fetch-zk-params.sh
112 |
113 | # Run the script to download ZK parameters
114 | ./fetch-zk-params.sh
115 | ```
116 |
117 | > **Note:**
118 | > - This script will generate a folder at `/.cache/midnight/zk-params` with all the required parameters for zero-knowledge proofs.
119 | > - **Why is this needed?** If you see an error like:
120 | > `Error in response: Proving(public parameters for k=16 not found in cache)`
121 | > it means the required parameters are missing.
122 | > - **This script is a workaround** to ensure your application works locally. The Midnight team is working on a more integrated solution for parameter management in the future.
123 |
124 | ### 4. Configure Compact Compiler
125 |
126 | To Install the compiler in your teminal follow these steps:
127 |
128 | **Download compiler**
129 |
130 | This command will download and run a shell script. It will instruct you how to add the binary directory it uses to your PATH environment variable.
131 |
132 | ```bash
133 | curl --proto '=https' --tlsv1.2 -LsSf https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh
134 | ```
135 |
136 | **Update compiler**
137 |
138 | Once you've done this, the compact command line tool is available to use. This tool has a number of useful subcommands that can be invoked. For instance, to update the toolchain to the latest version, you will run the command:
139 |
140 | ```bash
141 | compact update
142 | ```
143 |
144 | The output will look something like this (on an Apple Silicon macOS machine, for instance):
145 |
146 | ```bash
147 | compact: aarch64-darwin -- 0.24.0 -- installed
148 | compact: aarch64-darwin -- 0.24.0 -- default.
149 | ```
150 |
151 | **Check new version available**
152 |
153 | You can check if there is a new version available using the check subcommand like this:
154 |
155 | ```bash
156 | compact check
157 | ```
158 |
159 | If there is a new version available, you will see something like:
160 |
161 | ```
162 | compact: aarch64-darwin -- Update Available -- 0.24.0
163 | compact: Latest version available: 0.24.0.
164 | ```
165 |
166 | This is reporting that you are on version 0.24.0 and that 0.25.0 is available.
167 |
168 | **Note:**
169 | You will not actually see this output until there is a new version available. Instead, you will see that you are on the latest version:
170 |
171 | ```bash
172 | compact: aarch64-darwin -- Up to date -- 0.24.0
173 | ```
174 |
175 | **Invoking the Compiler**
176 |
177 | In addition to keeping the toolchain updated, the compact tool will also be the official supported way to invoke all the toolchain tools themselves. For the time being, the only such tool is the compiler, but we will be building out more tools in the future. The compiler can be invoked with the compile subcommand:
178 |
179 | ```bash
180 | compact compile