├── .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 181 | ``` 182 | 183 | You can see and learn more information, commands about the compiler here: [compact developer tools](https://docs.midnight.network/blog/compact-developer-tools) 184 | 185 | ### 5. Build All Packages 186 | 187 | ```bash 188 | # Build all packages (creates necessary folders automatically) 189 | yarn build:all 190 | ``` 191 | 192 | > **Note:** The build process automatically creates the necessary folders (`keys` and `zkir`) that are required by the frontend. No manual folder creation is needed. 193 | > 194 | > **What `yarn build:all` does:** 195 | > - Builds the contract package (compiles Compact contracts) 196 | > - Builds the API package (TypeScript compilation) 197 | > - Builds the CLI package (TypeScript compilation) 198 | > - Builds the UI package (Vite build with contract assets) 199 | > - Creates necessary folders for frontend compatibility 200 | 201 | ## 🏛️ Project Structure 202 | 203 | ### 📦 Main Packages 204 | 205 | #### `packages/ui/` - Frontend 206 | ``` 207 | ui/ 208 | ├── src/ 209 | │ ├── components/ # React Components 210 | │ ├── hooks/ # Custom hooks 211 | │ ├── lib/ # Utilities 212 | │ ├── providers/ # Context providers 213 | │ └── assets/ # Static resources 214 | ├── public/ # Public files 215 | └── dist/ # Production build 216 | ``` 217 | 218 | #### `packages/api/` - Backend API 219 | ``` 220 | api/ 221 | ├── src/ 222 | │ ├── index.ts # Entry point 223 | │ └── test/ # Tests 224 | └── dist/ # Compiled build 225 | ``` 226 | 227 | #### `packages/contract/` - Smart Contracts 228 | ``` 229 | contract/ 230 | ├── src/ 231 | │ ├── quick-starter.compact # Main contract 232 | │ ├── managed/ # Generated contracts 233 | │ └── index.ts # Exports 234 | └── dist/ # Compiled build 235 | ``` 236 | 237 | #### `packages/cli/` - CLI Tools 238 | ``` 239 | cli/ 240 | ├── src/ 241 | │ ├── launcher/ # Network launchers 242 | │ ├── config.ts # Configurations 243 | │ └── index.ts # Entry point 244 | └── dist/ # Compiled build 245 | ``` 246 | 247 | ### 🔧 Configuration 248 | 249 | - **`turbo.json`** - Monorepo configuration 250 | - **`package.json`** - Root dependencies and scripts 251 | - **`.eslintrc.js`** - Linting rules 252 | - **`tsconfig.json`** - TypeScript configuration 253 | 254 | ## 🔍 Quick Development Guide 255 | 256 | ### 🎯 Areas to Modify (Marked with TODO) 257 | 258 | To quickly find areas that need customization, search for `TODO` comments throughout the codebase: 259 | 260 | **Using your code editor's global search:** 261 | - **VS Code:** `Ctrl+Shift+F` (or `Cmd+Shift+F` on Mac) and search for `TODO` 262 | - **WebStorm/IntelliJ:** `Ctrl+Shift+F` and search for `TODO` 263 | - **Sublime Text:** `Ctrl+Shift+F` and search for `TODO` 264 | 265 | **Using command line:** 266 | ```bash 267 | # Search for all TODO comments 268 | grep -r "TODO" . 269 | 270 | # Or search in specific packages 271 | grep -r "TODO" packages/contract/ 272 | grep -r "TODO" packages/api/ 273 | grep -r "TODO" packages/ui/ 274 | grep -r "TODO" packages/cli/ 275 | ``` 276 | 277 | ### 📝 Key Files to Customize 278 | 279 | - **`packages/contract/src/quick-starter.compact`** - Your main smart contract 280 | - **`packages/contract/src/index.ts`** - Contract exports and logic 281 | - **`packages/api/src/index.ts`** - Backend API implementation 282 | - **`packages/cli/src/index.ts`** - CLI interaction logic 283 | - **`packages/ui/src/main.tsx`** - Main React application 284 | - **`packages/ui/src/components/`** - React components 285 | - **`packages/ui/src/hooks/`** - Custom React hooks 286 | - **`packages/ui/src/lib/`** - Utility functions 287 | - **`packages/ui/src/providers/`** - Context providers 288 | 289 | ### 🚀 Development Workflow 290 | 291 | 1. **Edit your contract** in `packages/contract/src/quick-starter.compact` 292 | 2. **Build the contract** with `cd packages/contract && npx turbo run build` 293 | 3. **Build other packages** as needed using individual build commands 294 | 4. **Customize UI components** in `packages/ui/src/` 295 | 5. **Implement API logic** in `packages/api/src/` 296 | 297 | ## 🐳 Docker Services 298 | 299 | After building your packages, you can run the Infrastructure services using Docker: 300 | 301 | ### Testnet Environment 302 | 303 | ```bash 304 | cd packages/cli 305 | docker compose -f testnet.yml up -d 306 | ``` 307 | 308 | ### Standalone Environment 309 | 310 | ```bash 311 | cd packages/cli 312 | docker compose -f standalone.yml up -d 313 | ``` 314 | 315 | > **Note:** The `-d` flag runs containers in detached mode (background), so you can continue using your terminal. 316 | 317 | You should see something like: 318 | ``` 319 | ✔ Container quick-starter-proof-server Started 320 | ✔ Container quick-starter-node Started 321 | ✔ Container quick-starter-indexer Started 322 | ``` 323 | 324 | ## 🚀 Running the Application 325 | 326 | ### Start the UI 327 | 328 | ```bash 329 | cd packages/ui 330 | yarn start 331 | ``` 332 | 333 | The application will be available at `localhost:8080` 334 | 335 | ## 🤝 Contributing 336 | 337 | ### Contribution Guidelines 338 | 339 | This is a template designed to be used as a starting point for new projects. You can: 340 | 341 | 1. **Use as Template** - Click "Use this template" to create a new repository 342 | 2. **Fork** the repository for your own project 343 | 3. **Contribute** - Any PR is welcome to improve the template 344 | 345 | If contributing: 346 | 1. **Fork** the repository 347 | 2. **Create** a feature branch (`git checkout -b feature/amazing-feature`) 348 | 3. **Commit** your changes (`git commit -m 'feat: add amazing feature'`) 349 | 4. **Push** to the branch (`git push origin feature/amazing-feature`) 350 | 5. **Open** a Pull Request 351 | 352 | ### Code Standards 353 | 354 | - Use **TypeScript** for all code 355 | - Follow configured **ESLint** and **Prettier** 356 | - Write **tests** for new features 357 | - Document **APIs** and complex functions 358 | 359 | ### Commit Structure 360 | 361 | ``` 362 | feat: new feature 363 | fix: bug fix 364 | docs: documentation 365 | style: code formatting 366 | refactor: refactoring 367 | test: tests 368 | chore: maintenance tasks 369 | ``` 370 | 371 | ## 📄 License 372 | 373 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. 374 | 375 | ## 🚀 Roadmap & Ideas for Improvement 376 | 377 | This template is designed to be a living project and welcomes suggestions and contributions for new features and improvements. Here are some ideas and known areas for future enhancement: 378 | 379 | - [ ] **Integrated ZK Parameter Management:** 380 | Instead of requiring a manual script, the ZK parameters could be downloaded automatically as part of the Docker image or build process. 381 | The infrastructure could check for missing parameters and fetch them on demand. 382 | 383 | - [x] **Better Developer Onboarding:** 384 | Add interactive setup scripts or a CLI wizard for first-time setup. 385 | Provide more example contracts, API endpoints, and UI components. 386 | 387 | - [x] **Automated Environment Checks:** 388 | Add pre-build checks for required tools, environment variables, and folder structure. 389 | 390 | - [ ] **Improved Error Handling:** 391 | More descriptive error messages and troubleshooting guides for common issues. 392 | 393 | - [ ] **Template Customization Tools:** 394 | Scripts to easily rename the template, update package names, and clean up example files. 395 | 396 | - [ ] **CI/CD Integration:** 397 | Add GitHub Actions or other CI pipelines for automated testing, linting, and deployment. 398 | 399 | - [ ] **Documentation Enhancements:** 400 | More diagrams, architecture overviews, and real-world usage examples. 401 | 402 | - [x] **Community Feedback:** 403 | Encourage users to open issues or discussions for feature requests and pain points. 404 | 405 | - [ ] **Unified CLI/Library for Project Management:** 406 | Create a library or CLI tool to automate all setup, configuration, and project management from a single command (e.g., midnight-quick-starter init). 407 | 408 | - [x] **Basic Hello World Contract Validation:** 409 | Add a minimal contract and test that simply sets and reads a "Hello World" message to validate that the toolchain and build are working correctly. 410 | 411 | - [ ] **Lace Beta Wallet Integration:** 412 | Add support and documentation for integrating with Lace Beta Wallet for user authentication and transaction signing in the UI. 413 | 414 | > **Have an idea?** Open an issue or pull request to help make this template even better! 415 | 416 | --- 417 | 418 | ## 🆘 Support 419 | 420 | If you have issues or questions: 421 | 422 | 1. Check the [documentation](docs/) 423 | 2. Search [existing issues](../../issues) 424 | 3. Create a [new issue](../../issues/new) 425 | 426 | ## 🔗 Useful Links 427 | 428 | - [Midnight Network Documentation](https://docs.midnight.network/) 429 | - [Compact Language Guide](https://docs.midnight.network/develop/reference/compact/) 430 | - [Turbo Documentation](https://turbo.build/repo/docs) 431 | - [React Documentation](https://react.dev/) 432 | - [TypeScript Documentation](https://www.typescriptlang.org/docs/) 433 | 434 | --- 435 | 436 | **⭐ If this template is useful to you, consider giving the repository a star!** 437 | 438 | --- 439 | 440 | **Made with ❤️ by the Midnight ecosystem** 441 | --------------------------------------------------------------------------------