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.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -0
- package/templates/storage/README.md +106 -0
- package/templates/storage/_gitignore +20 -0
- package/templates/storage/package-lock.json +15358 -0
- package/templates/storage/package.json +15 -0
- package/templates/storage/packages/contracts/contracts/FileRegistry.sol +49 -0
- package/templates/storage/packages/contracts/hardhat.config.ts +40 -0
- package/templates/storage/packages/contracts/package.json +15 -0
- package/templates/storage/packages/contracts/scripts/deploy.ts +43 -0
- package/templates/storage/packages/web/.env.example +12 -0
- package/templates/storage/packages/web/app/globals.css +23 -0
- package/templates/storage/packages/web/app/layout.tsx +25 -0
- package/templates/storage/packages/web/app/page.module.css +74 -0
- package/templates/storage/packages/web/app/page.tsx +29 -0
- package/templates/storage/packages/web/app/providers.tsx +14 -0
- package/templates/storage/packages/web/app/storage/page.module.css +110 -0
- package/templates/storage/packages/web/app/storage/page.tsx +167 -0
- package/templates/storage/packages/web/components/Navbar.module.css +92 -0
- package/templates/storage/packages/web/components/Navbar.tsx +42 -0
- package/templates/storage/packages/web/lib/0g-storage.ts +40 -0
- package/templates/storage/packages/web/lib/abi.ts +48 -0
- package/templates/storage/packages/web/lib/wagmi.ts +23 -0
- package/templates/storage/packages/web/next-env.d.ts +6 -0
- package/templates/storage/packages/web/next.config.ts +27 -0
- package/templates/storage/packages/web/package.json +26 -0
- package/templates/storage/packages/web/tsconfig.json +21 -0
package/dist/index.d.ts
ADDED
|
@@ -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
|