create-0g-app 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +149 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +33 -0
  6. package/templates/storage/README.md +106 -0
  7. package/templates/storage/_gitignore +20 -0
  8. package/templates/storage/package-lock.json +15358 -0
  9. package/templates/storage/package.json +15 -0
  10. package/templates/storage/packages/contracts/contracts/FileRegistry.sol +49 -0
  11. package/templates/storage/packages/contracts/hardhat.config.ts +40 -0
  12. package/templates/storage/packages/contracts/package.json +15 -0
  13. package/templates/storage/packages/contracts/scripts/deploy.ts +43 -0
  14. package/templates/storage/packages/web/.env.example +12 -0
  15. package/templates/storage/packages/web/app/globals.css +23 -0
  16. package/templates/storage/packages/web/app/layout.tsx +25 -0
  17. package/templates/storage/packages/web/app/page.module.css +74 -0
  18. package/templates/storage/packages/web/app/page.tsx +29 -0
  19. package/templates/storage/packages/web/app/providers.tsx +14 -0
  20. package/templates/storage/packages/web/app/storage/page.module.css +110 -0
  21. package/templates/storage/packages/web/app/storage/page.tsx +167 -0
  22. package/templates/storage/packages/web/components/Navbar.module.css +92 -0
  23. package/templates/storage/packages/web/components/Navbar.tsx +42 -0
  24. package/templates/storage/packages/web/lib/0g-storage.ts +40 -0
  25. package/templates/storage/packages/web/lib/abi.ts +48 -0
  26. package/templates/storage/packages/web/lib/wagmi.ts +23 -0
  27. package/templates/storage/packages/web/next-env.d.ts +6 -0
  28. package/templates/storage/packages/web/next.config.ts +27 -0
  29. package/templates/storage/packages/web/package.json +26 -0
  30. package/templates/storage/packages/web/tsconfig.json +21 -0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const p = __importStar(require("@clack/prompts"));
41
+ const picocolors_1 = __importDefault(require("picocolors"));
42
+ const path_1 = __importDefault(require("path"));
43
+ const fs_extra_1 = __importDefault(require("fs-extra"));
44
+ const child_process_1 = require("child_process");
45
+ const TEMPLATES = {
46
+ storage: "File registry (storage SDK + on-chain provenance)",
47
+ compute: "Decentralized chat (inference SDK + on-chain logging) — coming soon",
48
+ agent: "Autonomous agent (storage + compute + task contract) — coming soon",
49
+ };
50
+ async function main() {
51
+ console.log();
52
+ console.log(picocolors_1.default.cyan([
53
+ " ╔═══════════════════════════════════╗",
54
+ " ║ " + picocolors_1.default.bold("create-0g-app") + " v1.0.0 ║",
55
+ " ╚═══════════════════════════════════╝",
56
+ ].join("\n")));
57
+ console.log();
58
+ p.intro(picocolors_1.default.bgCyan(picocolors_1.default.black(" 0G App Scaffolder ")));
59
+ // Project name from CLI arg or prompt
60
+ let projectName = process.argv[2];
61
+ if (!projectName) {
62
+ const name = await p.text({
63
+ message: "Project name:",
64
+ placeholder: "my-0g-app",
65
+ validate: (v) => {
66
+ if (!v)
67
+ return "Project name is required";
68
+ if (!/^[a-z0-9-_]+$/i.test(v))
69
+ return "Only letters, numbers, hyphens and underscores";
70
+ },
71
+ });
72
+ if (p.isCancel(name)) {
73
+ p.cancel("Cancelled.");
74
+ process.exit(0);
75
+ }
76
+ projectName = name;
77
+ }
78
+ const template = await p.select({
79
+ message: "Which template would you like to use?",
80
+ options: Object.entries(TEMPLATES).map(([value, label]) => ({ value, label: `${value.padEnd(10)} — ${label}` })),
81
+ });
82
+ if (p.isCancel(template)) {
83
+ p.cancel("Cancelled.");
84
+ process.exit(0);
85
+ }
86
+ const targetDir = path_1.default.resolve(process.cwd(), projectName);
87
+ if (fs_extra_1.default.existsSync(targetDir)) {
88
+ const overwrite = await p.confirm({
89
+ message: `Directory ${picocolors_1.default.yellow(projectName)} already exists. Overwrite?`,
90
+ initialValue: false,
91
+ });
92
+ if (p.isCancel(overwrite) || !overwrite) {
93
+ p.cancel("Cancelled.");
94
+ process.exit(0);
95
+ }
96
+ fs_extra_1.default.removeSync(targetDir);
97
+ }
98
+ const s = p.spinner();
99
+ // Copy template
100
+ s.start("Scaffolding project");
101
+ const templateDir = path_1.default.join(__dirname, "..", "templates", template);
102
+ if (!fs_extra_1.default.existsSync(templateDir)) {
103
+ s.stop(picocolors_1.default.yellow(`The "${template}" template is coming soon! Only "storage" is available right now.`));
104
+ process.exit(0);
105
+ }
106
+ fs_extra_1.default.copySync(templateDir, targetDir, {
107
+ filter: (src) => !src.includes("node_modules") && !src.includes(".next"),
108
+ });
109
+ // Rename gitignore (npm strips .gitignore on publish)
110
+ const gitignoreSrc = path_1.default.join(targetDir, "_gitignore");
111
+ const gitignoreDest = path_1.default.join(targetDir, ".gitignore");
112
+ if (fs_extra_1.default.existsSync(gitignoreSrc))
113
+ fs_extra_1.default.moveSync(gitignoreSrc, gitignoreDest);
114
+ // Write .env from .env.example in web package
115
+ const envExample = path_1.default.join(targetDir, "packages", "web", ".env.example");
116
+ const envDest = path_1.default.join(targetDir, "packages", "web", ".env.local");
117
+ if (fs_extra_1.default.existsSync(envExample) && !fs_extra_1.default.existsSync(envDest)) {
118
+ fs_extra_1.default.copySync(envExample, envDest);
119
+ }
120
+ s.stop(`Scaffolded project in ${picocolors_1.default.green(`./${projectName}`)}`);
121
+ // Install dependencies — stream output directly so user can see progress
122
+ console.log(picocolors_1.default.dim("\n Installing dependencies... (this may take a minute, hang tight)\n"));
123
+ try {
124
+ (0, child_process_1.execSync)("npm install", { cwd: targetDir, stdio: "inherit" });
125
+ console.log();
126
+ p.log.success("Dependencies installed");
127
+ }
128
+ catch {
129
+ p.log.warn("Dependency install failed — run `npm install` manually inside the project");
130
+ }
131
+ p.outro([
132
+ picocolors_1.default.green("Your 0G app is ready!"),
133
+ "",
134
+ " " + picocolors_1.default.dim("Next steps:"),
135
+ "",
136
+ ` ${picocolors_1.default.cyan(`cd ${projectName}`)}`,
137
+ ` ${picocolors_1.default.dim("# Add your private key to packages/web/.env.local")}`,
138
+ ` ${picocolors_1.default.cyan("npm run dev")} ${picocolors_1.default.dim("→ local dev server")}`,
139
+ ` ${picocolors_1.default.cyan("npm run deploy")} ${picocolors_1.default.dim("→ compile + deploy contract to Galileo testnet")}`,
140
+ ` ${picocolors_1.default.cyan("npm run verify")} ${picocolors_1.default.dim("→ verify contract on 0G explorer")}`,
141
+ "",
142
+ ` ${picocolors_1.default.dim("Docs: https://docs.0g.ai")}`,
143
+ ].join("\n"));
144
+ }
145
+ main().catch((e) => {
146
+ console.error(e);
147
+ process.exit(1);
148
+ });
149
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "create-0g-app",
3
+ "version": "1.0.0",
4
+ "description": "Zero-config scaffold CLI for building on the 0G decentralized AI network",
5
+ "bin": {
6
+ "create-0g-app": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist",
10
+ "templates"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsc --watch",
15
+ "start": "node dist/index.js",
16
+ "prepare": "npm run build"
17
+ },
18
+ "keywords": ["0g", "scaffold", "cli", "web3", "ai", "decentralized"],
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "@clack/prompts": "^0.9.1",
22
+ "fs-extra": "^11.2.0",
23
+ "picocolors": "^1.1.1"
24
+ },
25
+ "devDependencies": {
26
+ "@types/fs-extra": "^11.0.4",
27
+ "@types/node": "^22.0.0",
28
+ "typescript": "^5.7.0"
29
+ },
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ }
33
+ }
@@ -0,0 +1,106 @@
1
+ # 0G Storage App
2
+
3
+ A decentralized file registry built on the [0G network](https://0g.ai).
4
+
5
+ - **Files** are stored on 0G's decentralized storage network via `@0glabs/0g-ts-sdk`
6
+ - **Provenance** (who uploaded what, and when) is recorded on-chain via `FileRegistry.sol`
7
+ - **Frontend** is a Next.js 15 app with wagmi wallet connect
8
+
9
+ ## Quick Start
10
+
11
+ ### 1. Install dependencies
12
+
13
+ ```bash
14
+ npm install
15
+ ```
16
+
17
+ ### 2. Configure environment
18
+
19
+ ```bash
20
+ cp packages/web/.env.example packages/web/.env.local
21
+ ```
22
+
23
+ Edit `packages/web/.env.local` and add your private key:
24
+
25
+ ```env
26
+ PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
27
+ ```
28
+
29
+ > Get testnet OG tokens from the [0G faucet](https://faucet.0g.ai) if your wallet is empty.
30
+
31
+ ### 3. Start the dev server (no deploy needed)
32
+
33
+ ```bash
34
+ npm run dev
35
+ ```
36
+
37
+ Open [http://localhost:3000](http://localhost:3000). You can browse the UI, but uploads need the contract deployed first.
38
+
39
+ ### 4. Deploy the contract to Galileo testnet
40
+
41
+ ```bash
42
+ npm run deploy
43
+ ```
44
+
45
+ This will:
46
+ 1. Compile `FileRegistry.sol`
47
+ 2. Deploy it to the 0G Galileo testnet (chain ID 16601)
48
+ 3. Automatically write the contract address to `packages/web/.env.local`
49
+
50
+ Restart the dev server after deploying to pick up the new address.
51
+
52
+ ### 5. Verify the contract (optional)
53
+
54
+ ```bash
55
+ npm run verify
56
+ ```
57
+
58
+ View your contract on the [0G Galileo explorer](https://chainscan-galileo.0g.ai).
59
+
60
+ ## Project Structure
61
+
62
+ ```
63
+ ├── packages/
64
+ │ ├── contracts/ Solidity + Hardhat
65
+ │ │ ├── contracts/
66
+ │ │ │ └── FileRegistry.sol
67
+ │ │ ├── scripts/
68
+ │ │ │ └── deploy.ts
69
+ │ │ └── hardhat.config.ts
70
+ │ └── web/ Next.js frontend
71
+ │ ├── app/
72
+ │ ├── lib/
73
+ │ │ ├── 0g-storage.ts 0G SDK wrapper
74
+ │ │ ├── abi.ts FileRegistry ABI
75
+ │ │ └── wagmi.ts Wallet config
76
+ │ └── .env.example
77
+ └── README.md
78
+ ```
79
+
80
+ ## How It Works
81
+
82
+ 1. User connects their wallet (MetaMask or any injected wallet)
83
+ 2. User drops a file onto the upload zone
84
+ 3. The file is uploaded to 0G storage via the indexer — a content ID (merkle root) is returned
85
+ 4. The content ID is written on-chain to `FileRegistry.sol` via `registerFile()`
86
+ 5. The file gallery reads all content IDs from the contract for the connected wallet
87
+ 6. Clicking "Download" fetches the file from 0G storage by content ID
88
+
89
+ ## Troubleshooting
90
+
91
+ **"No contract deployed yet" warning**
92
+ Run `npm run deploy` and restart the dev server.
93
+
94
+ **Transaction fails / insufficient funds**
95
+ Get testnet OG tokens from [https://faucet.0g.ai](https://faucet.0g.ai).
96
+
97
+ **Upload hangs**
98
+ The 0G storage indexer may be temporarily unavailable. Check [https://docs.0g.ai](https://docs.0g.ai) for status.
99
+
100
+ **Wrong network in MetaMask**
101
+ Add the 0G Galileo testnet manually:
102
+ - Network name: 0G Galileo Testnet
103
+ - RPC URL: https://evmrpc-test.0g.ai
104
+ - Chain ID: 16601
105
+ - Currency: OG
106
+ - Explorer: https://chainscan-galileo.0g.ai
@@ -0,0 +1,20 @@
1
+ # deps
2
+ node_modules/
3
+
4
+ # Next.js
5
+ packages/web/.next/
6
+ packages/web/out/
7
+
8
+ # Hardhat
9
+ packages/contracts/artifacts/
10
+ packages/contracts/cache/
11
+ packages/contracts/typechain-types/
12
+ packages/contracts/.deployed-address
13
+
14
+ # env — never commit private keys
15
+ packages/web/.env.local
16
+ packages/web/.env
17
+
18
+ # misc
19
+ .DS_Store
20
+ *.log