create-dig-app 0.3.0 → 0.3.2
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/README.md +50 -42
- package/lib/cli.js +18 -8
- package/lib/index.js +5 -6
- package/lib/nft-cli.js +13 -12
- package/lib/nft-metadata.js +16 -5
- package/lib/templates.js +7 -8
- package/package.json +6 -3
- package/templates/dapp-window-chia/src/App.jsx +4 -4
- package/templates/dapp-window-chia/src/styles.css +35 -11
- package/templates/next-static/app/globals.css +18 -7
- package/templates/next-static/app/page.jsx +2 -2
- package/templates/nft-collection/collection.json +1 -3
- package/templates/nft-collection/scripts/dig-nft.mjs +145 -62
- package/templates/nft-collection/src/styles.css +53 -14
- package/templates/nft-drop/src/App.jsx +5 -5
- package/templates/nft-drop/src/styles.css +31 -10
- package/templates/static-site/src/index.html +3 -3
- package/templates/static-site/src/styles.css +18 -7
- package/templates/vite-react/src/App.jsx +2 -2
- package/templates/vite-react/src/styles.css +18 -7
- package/templates-ts/dapp-window-chia/src/App.tsx +4 -4
- package/templates-ts/dapp-window-chia/src/styles.css +35 -11
- package/templates-ts/dapp-window-chia/src/wallet.ts +1 -5
- package/templates-ts/next-static/app/globals.css +18 -7
- package/templates-ts/next-static/app/page.tsx +2 -2
- package/templates-ts/nft-drop/src/App.tsx +5 -5
- package/templates-ts/nft-drop/src/mint.ts +1 -5
- package/templates-ts/nft-drop/src/styles.css +31 -10
- package/templates-ts/vite-react/src/App.tsx +2 -2
- package/templates-ts/vite-react/src/styles.css +18 -7
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ types** — `ChiaProvider`, `ConnectOptions`, and friends are fully typed straig
|
|
|
45
45
|
|
|
46
46
|
**Scaffolding, building, and previewing cost nothing.** Creating a project does **not** mint,
|
|
47
47
|
touch the chain, or spend any funds. You spend **$DIG** only when you publish a **capsule** with
|
|
48
|
-
`digstore deploy`.
|
|
48
|
+
`digstore deploy`. _Iterate for free, publish when it's ready._
|
|
49
49
|
|
|
50
50
|
```sh
|
|
51
51
|
digstore dev # preview on the real chia:// read path — FREE, no chain, no spend
|
|
@@ -57,16 +57,16 @@ human name so it is also reachable at `<your-name>.on.dig.net` (a pay-to-registe
|
|
|
57
57
|
|
|
58
58
|
## Templates
|
|
59
59
|
|
|
60
|
-
| Template
|
|
61
|
-
|
|
62
|
-
| `static-site`
|
|
63
|
-
| `vite-react`
|
|
64
|
-
| `next-static`
|
|
65
|
-
| `nft-drop`
|
|
66
|
-
| `nft-collection`
|
|
67
|
-
| `dapp-window-chia` | A dapp wired to a Chia wallet via `ChiaProvider` — injected `window.chia`, or Sage over WalletConnect. | yes
|
|
60
|
+
| Template | What you get | Wallet wired | Languages |
|
|
61
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------ | ------------ | --------- |
|
|
62
|
+
| `static-site` | Plain HTML/CSS/JS — zero build step, the lightest way to ship a site. | — | JS |
|
|
63
|
+
| `vite-react` | A React SPA built with Vite — the fast default for an app frontend. | — | JS · TS |
|
|
64
|
+
| `next-static` | Next.js exported to static files (`output: 'export'`), deployable as a capsule. | — | JS · TS |
|
|
65
|
+
| `nft-drop` | A wallet-connected NFT mint page (`ChiaProvider` + the canonical CHIP-0035 spend builder). | yes | JS · TS |
|
|
66
|
+
| `nft-collection` | An NFT collection workspace — art + CHIP-0007 metadata/license tooling for `digstore collection mint`. | yes | JS |
|
|
67
|
+
| `dapp-window-chia` | A dapp wired to a Chia wallet via `ChiaProvider` — injected `window.chia`, or Sage over WalletConnect. | yes | JS · TS |
|
|
68
68
|
|
|
69
|
-
The **`nft-collection`** template is a
|
|
69
|
+
The **`nft-collection`** template is a _collection workspace_, not a single page: drop your art in
|
|
70
70
|
`images/`, describe the set once in `collection.json`, and its dependency-free tooling
|
|
71
71
|
(`npm run generate` / `npm run validate`) emits the canonical **CHIP-0007** metadata + the
|
|
72
72
|
`items.json` manifest that `digstore collection mint` consumes — byte-for-byte the same shape the
|
|
@@ -84,11 +84,11 @@ scaffold time** — minting is an explicit, wallet-signed action a user triggers
|
|
|
84
84
|
|
|
85
85
|
The same **Connect** button works in both worlds, in both JS and TS:
|
|
86
86
|
|
|
87
|
-
|
|
|
88
|
-
|
|
89
|
-
| When
|
|
90
|
-
| Setup | none
|
|
91
|
-
| UX
|
|
87
|
+
| | Injected (DIG Browser / extension) | WalletConnect → Sage (any browser) |
|
|
88
|
+
| ----- | ---------------------------------- | ------------------------------------ |
|
|
89
|
+
| When | `window.chia` is present | no injected wallet found |
|
|
90
|
+
| Setup | none | set a free **projectId** (env) |
|
|
91
|
+
| UX | instant connect | pairing link / QR to approve in Sage |
|
|
92
92
|
|
|
93
93
|
To enable the Sage fallback, the wallet templates ship `@walletconnect/sign-client` (the SDK's
|
|
94
94
|
optional WC peer dep) as a dependency and read a **project id** from the build-time env:
|
|
@@ -120,18 +120,18 @@ npm create dig-app@latest
|
|
|
120
120
|
npm create dig-app@latest -- --help
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
| Option
|
|
124
|
-
|
|
125
|
-
| `<name>`
|
|
126
|
-
| `-t, --template <t>`
|
|
127
|
-
| `--typescript`, `--ts` | Scaffold the TypeScript variant (where available).
|
|
128
|
-
| `--javascript`, `--js` | Scaffold the JavaScript variant (the default).
|
|
129
|
-
| `--lang <js\|ts>`
|
|
130
|
-
| `--json`
|
|
131
|
-
| `--list-templates`
|
|
132
|
-
| `--help-json`
|
|
133
|
-
| `-h, --help`
|
|
134
|
-
| `-v, --version`
|
|
123
|
+
| Option | Description |
|
|
124
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
125
|
+
| `<name>` | Project directory + npm package name (slugified to be npm-safe). |
|
|
126
|
+
| `-t, --template <t>` | One of: `static-site`, `vite-react`, `next-static`, `nft-drop`, `nft-collection`, `dapp-window-chia`. |
|
|
127
|
+
| `--typescript`, `--ts` | Scaffold the TypeScript variant (where available). |
|
|
128
|
+
| `--javascript`, `--js` | Scaffold the JavaScript variant (the default). |
|
|
129
|
+
| `--lang <js\|ts>` | Same as the language flags above. |
|
|
130
|
+
| `--json` | Emit one structured result object on stdout; route human prose to stderr (for scripts/agents). |
|
|
131
|
+
| `--list-templates` | List the available templates (pair with `--json` for machine-readable output). |
|
|
132
|
+
| `--help-json` | Print the full flag/template tree + exit-code table as JSON. |
|
|
133
|
+
| `-h, --help` | Show usage and the template list. |
|
|
134
|
+
| `-v, --version` | Print the version. |
|
|
135
135
|
|
|
136
136
|
> The `--` before the flags is npm's `npm create` argument separator — it forwards the rest to
|
|
137
137
|
> `create-dig-app`. With `npx create-dig-app` / `pnpm create dig-app` you can drop it.
|
|
@@ -177,26 +177,34 @@ On failure, `--json` emits a structured error envelope with a **stable, UPPER_SN
|
|
|
177
177
|
derived from the prose), the matching exit code, and an actionable hint:
|
|
178
178
|
|
|
179
179
|
```json
|
|
180
|
-
{
|
|
181
|
-
"
|
|
182
|
-
"
|
|
180
|
+
{
|
|
181
|
+
"schemaVersion": 1,
|
|
182
|
+
"ok": false,
|
|
183
|
+
"error": {
|
|
184
|
+
"code": "UNKNOWN_TEMPLATE",
|
|
185
|
+
"exit_code": 3,
|
|
186
|
+
"message": "Unknown template \"svelte\". Available: …",
|
|
187
|
+
"hint": "Run with --list-templates …",
|
|
188
|
+
"template": "svelte"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
183
191
|
```
|
|
184
192
|
|
|
185
193
|
### Exit codes
|
|
186
194
|
|
|
187
195
|
A differentiated, stable exit-code table (also emitted by `--help-json`) so a script can branch on
|
|
188
|
-
the
|
|
189
|
-
|
|
190
|
-
| Code | Meaning
|
|
191
|
-
|
|
192
|
-
| `0`
|
|
193
|
-
| `1`
|
|
194
|
-
| `2`
|
|
195
|
-
| `3`
|
|
196
|
-
| `4`
|
|
197
|
-
| `5`
|
|
198
|
-
| `6`
|
|
199
|
-
| `7`
|
|
196
|
+
the _kind_ of failure:
|
|
197
|
+
|
|
198
|
+
| Code | Meaning |
|
|
199
|
+
| ---- | ------------------------------------------------------- |
|
|
200
|
+
| `0` | success |
|
|
201
|
+
| `1` | unexpected internal error |
|
|
202
|
+
| `2` | usage error (bad/unknown option or malformed arguments) |
|
|
203
|
+
| `3` | unknown template id |
|
|
204
|
+
| `4` | target directory exists and is not empty |
|
|
205
|
+
| `5` | required arguments missing in non-interactive mode |
|
|
206
|
+
| `6` | bundled template files are missing (packaging bug) |
|
|
207
|
+
| `7` | app name is not usable |
|
|
200
208
|
|
|
201
209
|
## Develop on create-dig-app
|
|
202
210
|
|
package/lib/cli.js
CHANGED
|
@@ -79,7 +79,8 @@ export function parseArgs(argv) {
|
|
|
79
79
|
else if (a === "--javascript" || a === "--js") out.lang = "js";
|
|
80
80
|
else if (a === "--lang") out.lang = normalizeLang(argv[++i]);
|
|
81
81
|
else if (a.startsWith("--lang=")) out.lang = normalizeLang(a.slice("--lang=".length));
|
|
82
|
-
else if (a === "--")
|
|
82
|
+
else if (a === "--")
|
|
83
|
+
continue; // npm-init separator
|
|
83
84
|
else if (a.startsWith("-")) throw new Error(`Unknown option: ${a}`);
|
|
84
85
|
else if (out.appName === undefined) out.appName = a;
|
|
85
86
|
// ignore extra positionals
|
|
@@ -153,7 +154,11 @@ export function helpJson() {
|
|
|
153
154
|
summary: "Scaffold a wallet-wired, deployable DIG Network app (free, no mint).",
|
|
154
155
|
flags: [
|
|
155
156
|
{ name: "--template", alias: "-t", value: "<template>", description: "The template to scaffold." },
|
|
156
|
-
{
|
|
157
|
+
{
|
|
158
|
+
name: "--typescript",
|
|
159
|
+
aliases: ["--ts"],
|
|
160
|
+
description: "Scaffold the TypeScript variant (where available).",
|
|
161
|
+
},
|
|
157
162
|
{ name: "--javascript", aliases: ["--js"], description: "Scaffold the JavaScript variant (default)." },
|
|
158
163
|
{ name: "--lang", value: "<js|ts>", description: "Same as the language flags." },
|
|
159
164
|
{ name: "--json", description: "Emit one structured result object on stdout; route prose to stderr." },
|
|
@@ -163,9 +168,7 @@ export function helpJson() {
|
|
|
163
168
|
{ name: "--version", alias: "-v", description: "Print the version." },
|
|
164
169
|
],
|
|
165
170
|
templates: listTemplatesJson(),
|
|
166
|
-
exitCodes: Object.fromEntries(
|
|
167
|
-
Object.entries(EXIT_MEANINGS).map(([code, meaning]) => [code, meaning]),
|
|
168
|
-
),
|
|
171
|
+
exitCodes: Object.fromEntries(Object.entries(EXIT_MEANINGS).map(([code, meaning]) => [code, meaning])),
|
|
169
172
|
};
|
|
170
173
|
}
|
|
171
174
|
|
|
@@ -307,7 +310,12 @@ export async function run(argv, io = {}) {
|
|
|
307
310
|
} catch (e) {
|
|
308
311
|
// A parse failure (unknown option / bad --lang) is a USAGE error.
|
|
309
312
|
if (argvHasJson(argv)) {
|
|
310
|
-
emitJsonError(out, {
|
|
313
|
+
emitJsonError(out, {
|
|
314
|
+
code: "BAD_USAGE",
|
|
315
|
+
exit_code: EXIT.USAGE,
|
|
316
|
+
message: e.message,
|
|
317
|
+
hint: "Run with --help for usage.",
|
|
318
|
+
});
|
|
311
319
|
} else {
|
|
312
320
|
log(e.message);
|
|
313
321
|
log("Run with --help for usage.");
|
|
@@ -334,7 +342,8 @@ export async function run(argv, io = {}) {
|
|
|
334
342
|
return EXIT.SUCCESS;
|
|
335
343
|
}
|
|
336
344
|
if (args.version) {
|
|
337
|
-
if (json)
|
|
345
|
+
if (json)
|
|
346
|
+
out(JSON.stringify({ schemaVersion: SCHEMA_VERSION, version: io.version ?? "unknown" }, null, 2));
|
|
338
347
|
else log(io.version ?? "unknown");
|
|
339
348
|
return EXIT.SUCCESS;
|
|
340
349
|
}
|
|
@@ -351,7 +360,8 @@ export async function run(argv, io = {}) {
|
|
|
351
360
|
emitJsonError(out, {
|
|
352
361
|
code: "MISSING_ARGS",
|
|
353
362
|
exit_code: EXIT.MISSING_ARGS,
|
|
354
|
-
message:
|
|
363
|
+
message:
|
|
364
|
+
"Missing required arguments: <name> and --template are required in non-interactive mode.",
|
|
355
365
|
hint: "Pass a name and --template, e.g. `create-dig-app my-app --template vite-react --json`.",
|
|
356
366
|
});
|
|
357
367
|
} else {
|
package/lib/index.js
CHANGED
|
@@ -82,7 +82,7 @@ function templateSrcDir(meta, lang) {
|
|
|
82
82
|
// these under a `_`-prefixed name and we rename them back on scaffold.
|
|
83
83
|
const RENAME_ON_COPY = {
|
|
84
84
|
_gitignore: ".gitignore",
|
|
85
|
-
|
|
85
|
+
_npmrc: ".npmrc",
|
|
86
86
|
// Wallet templates ship a sample env (the WalletConnect projectId). npm's packing rules around
|
|
87
87
|
// dotfiles are finicky, so we ship it `_`-prefixed and restore the real `.env.example` on scaffold.
|
|
88
88
|
"_env.example": ".env.example",
|
|
@@ -154,7 +154,9 @@ export function scaffold({ appName, template, lang, targetDir }) {
|
|
|
154
154
|
|
|
155
155
|
if (!targetDir) throw new Error("targetDir is required");
|
|
156
156
|
if (!isEmptyDir(targetDir)) {
|
|
157
|
-
throw new Error(
|
|
157
|
+
throw new Error(
|
|
158
|
+
`target directory "${targetDir}" exists and is not empty — choose a new name or empty it.`,
|
|
159
|
+
);
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
const src = templateSrcDir(meta, resolvedLang);
|
|
@@ -211,10 +213,7 @@ export function scaffold({ appName, template, lang, targetDir }) {
|
|
|
211
213
|
* @returns {string[]}
|
|
212
214
|
*/
|
|
213
215
|
export function nextSteps({ slug, meta }) {
|
|
214
|
-
const steps = [
|
|
215
|
-
`cd ${slug}`,
|
|
216
|
-
`npm install`,
|
|
217
|
-
];
|
|
216
|
+
const steps = [`cd ${slug}`, `npm install`];
|
|
218
217
|
// `nft-collection` is an asset workspace, not a dev-server app: instead of `npm run dev` it has a
|
|
219
218
|
// generate → validate loop that produces the canonical CHIP-0007 metadata + the mint manifest.
|
|
220
219
|
if (meta.name === "nft-collection") {
|
package/lib/nft-cli.js
CHANGED
|
@@ -12,14 +12,7 @@
|
|
|
12
12
|
// and `metadata/*.json` are the off-chain CHIP-0007 docs `metadata_uris` points at. (SYSTEM.md →
|
|
13
13
|
// "CHIP-0007 NFT metadata"; the asset CLI `collection mint`.)
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
existsSync,
|
|
17
|
-
mkdirSync,
|
|
18
|
-
readFileSync,
|
|
19
|
-
readdirSync,
|
|
20
|
-
statSync,
|
|
21
|
-
writeFileSync,
|
|
22
|
-
} from "node:fs";
|
|
15
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
23
16
|
import { basename, extname, join } from "node:path";
|
|
24
17
|
|
|
25
18
|
import {
|
|
@@ -100,7 +93,10 @@ function resolveItems(root, imageFiles) {
|
|
|
100
93
|
* @returns {{count:number, manifestPath:string, metadataDir:string}}
|
|
101
94
|
*/
|
|
102
95
|
export function generateMetadata(root, opts = {}) {
|
|
103
|
-
|
|
96
|
+
// An empty / whitespace-only storeId falls back to the placeholder — never emit an empty-store-id
|
|
97
|
+
// URI (`urn:dig:chia:/…`). The CLI (dig-nft.mjs) rejects an explicitly-empty `--store-id` louder;
|
|
98
|
+
// here we coerce defensively so a programmatic caller can't produce a broken URN. (#1065)
|
|
99
|
+
const storeId = opts.storeId && String(opts.storeId).trim() ? opts.storeId : PLACEHOLDER_STORE_ID;
|
|
104
100
|
const collection = loadCollection(root);
|
|
105
101
|
const imageFiles = listImages(root);
|
|
106
102
|
const items = resolveItems(root, imageFiles);
|
|
@@ -216,7 +212,9 @@ export function validateProject(root) {
|
|
|
216
212
|
|
|
217
213
|
const metadataDir = join(root, "metadata");
|
|
218
214
|
const metaFiles = existsSync(metadataDir)
|
|
219
|
-
? readdirSync(metadataDir)
|
|
215
|
+
? readdirSync(metadataDir)
|
|
216
|
+
.filter((f) => f.endsWith(".json"))
|
|
217
|
+
.sort()
|
|
220
218
|
: [];
|
|
221
219
|
|
|
222
220
|
// Validate each on-disk metadata doc: schema + canonical-JSON stability.
|
|
@@ -239,7 +237,8 @@ export function validateProject(root) {
|
|
|
239
237
|
if (media.metadata_hash != null) {
|
|
240
238
|
// Find the metadata file whose canonical hash matches; otherwise verify against the rebuilt doc.
|
|
241
239
|
const matches = metaFiles.some(
|
|
242
|
-
(f) =>
|
|
240
|
+
(f) =>
|
|
241
|
+
metadataHashHex(JSON.parse(readFileSync(join(metadataDir, f), "utf8"))) === media.metadata_hash,
|
|
243
242
|
);
|
|
244
243
|
if (!matches && metadataHashHex(md) !== media.metadata_hash) {
|
|
245
244
|
throw new Error(`item "${item.name}": metadata_hash does not match any metadata/*.json`);
|
|
@@ -257,7 +256,9 @@ export function validateProject(root) {
|
|
|
257
256
|
if (licFile && media.license_hash != null) {
|
|
258
257
|
const licPath = join(root, licFile);
|
|
259
258
|
if (!existsSync(licPath)) throw new Error(`item "${item.name}": license not found at ${licFile}`);
|
|
260
|
-
validateMetadata(md, {
|
|
259
|
+
validateMetadata(md, {
|
|
260
|
+
license: { license_hash: media.license_hash, license_bytes: readFileSync(licPath) },
|
|
261
|
+
});
|
|
261
262
|
}
|
|
262
263
|
checked++;
|
|
263
264
|
}
|
package/lib/nft-metadata.js
CHANGED
|
@@ -65,7 +65,10 @@ function attrValue(v) {
|
|
|
65
65
|
*/
|
|
66
66
|
function normalizeAttributes(attrs) {
|
|
67
67
|
return (attrs ?? [])
|
|
68
|
-
.map((a) => ({
|
|
68
|
+
.map((a) => ({
|
|
69
|
+
trait_type: String(a?.trait_type ?? a?.traitType ?? "").trim(),
|
|
70
|
+
value: attrValue(a?.value),
|
|
71
|
+
}))
|
|
69
72
|
.filter((a) => a.trait_type !== "");
|
|
70
73
|
}
|
|
71
74
|
|
|
@@ -222,7 +225,9 @@ const DESC_KEYS = new Set(["description", "desc"]);
|
|
|
222
225
|
|
|
223
226
|
/** Classify a manifest column header into its role; anything else is a trait column. */
|
|
224
227
|
function classifyKey(key) {
|
|
225
|
-
const k = String(key ?? "")
|
|
228
|
+
const k = String(key ?? "")
|
|
229
|
+
.trim()
|
|
230
|
+
.toLowerCase();
|
|
226
231
|
if (NAME_KEYS.has(k)) return "name";
|
|
227
232
|
if (FILE_KEYS.has(k)) return "file";
|
|
228
233
|
if (DESC_KEYS.has(k)) return "description";
|
|
@@ -382,7 +387,9 @@ export const CAPSULE_HTTPS_GATEWAY = "usercontent.dig.net";
|
|
|
382
387
|
export function capsuleResourceUris({ storeId, root, resource }) {
|
|
383
388
|
const sid = String(storeId ?? "").trim();
|
|
384
389
|
const r = String(root ?? "").trim();
|
|
385
|
-
const res = String(resource ?? "")
|
|
390
|
+
const res = String(resource ?? "")
|
|
391
|
+
.trim()
|
|
392
|
+
.replace(/^\/+/, "");
|
|
386
393
|
const urn = `urn:dig:chia:${sid}${r ? `:${r}` : ""}/${res}`;
|
|
387
394
|
const https = `https://${sid}.${CAPSULE_HTTPS_GATEWAY}/${res}`;
|
|
388
395
|
return { urn, https, uris: [urn, https] };
|
|
@@ -536,13 +543,17 @@ export function validateMetadata(md, checks = {}) {
|
|
|
536
543
|
if (checks.media?.data_hash != null && checks.media?.data_bytes != null) {
|
|
537
544
|
const got = sha256Hex(checks.media.data_bytes);
|
|
538
545
|
if (got !== String(checks.media.data_hash).toLowerCase()) {
|
|
539
|
-
throw new ValidationError(
|
|
546
|
+
throw new ValidationError(
|
|
547
|
+
`data_hash mismatch: image bytes hash to ${got}, expected ${checks.media.data_hash}`,
|
|
548
|
+
);
|
|
540
549
|
}
|
|
541
550
|
}
|
|
542
551
|
if (checks.license?.license_hash != null && checks.license?.license_bytes != null) {
|
|
543
552
|
const got = sha256Hex(checks.license.license_bytes);
|
|
544
553
|
if (got !== String(checks.license.license_hash).toLowerCase()) {
|
|
545
|
-
throw new ValidationError(
|
|
554
|
+
throw new ValidationError(
|
|
555
|
+
`license_hash mismatch: license bytes hash to ${got}, expected ${checks.license.license_hash}`,
|
|
556
|
+
);
|
|
546
557
|
}
|
|
547
558
|
}
|
|
548
559
|
}
|
package/lib/templates.js
CHANGED
|
@@ -86,7 +86,8 @@ export const TEMPLATES = {
|
|
|
86
86
|
"nft-collection": {
|
|
87
87
|
name: "nft-collection",
|
|
88
88
|
title: "NFT collection",
|
|
89
|
-
description:
|
|
89
|
+
description:
|
|
90
|
+
"An NFT collection workspace — art + CHIP-0007 metadata/license tooling for digstore collection mint.",
|
|
90
91
|
outputDir: ".",
|
|
91
92
|
buildCommand: "npm run build",
|
|
92
93
|
wallet: true,
|
|
@@ -111,7 +112,9 @@ export const TEMPLATES = {
|
|
|
111
112
|
* @throws {Error} on an unrecognized value.
|
|
112
113
|
*/
|
|
113
114
|
export function normalizeLang(raw) {
|
|
114
|
-
const v = String(raw ?? "")
|
|
115
|
+
const v = String(raw ?? "")
|
|
116
|
+
.trim()
|
|
117
|
+
.toLowerCase();
|
|
115
118
|
if (v === "ts" || v === "typescript") return "ts";
|
|
116
119
|
if (v === "js" || v === "javascript") return "js";
|
|
117
120
|
throw new Error(`Unknown --lang "${raw}". Use "js" (javascript) or "ts" (typescript).`);
|
|
@@ -145,9 +148,7 @@ export const TEMPLATE_ALIASES = {
|
|
|
145
148
|
export class UnknownTemplateError extends Error {
|
|
146
149
|
/** @param {string} requested */
|
|
147
150
|
constructor(requested) {
|
|
148
|
-
super(
|
|
149
|
-
`Unknown template "${requested}". Available: ${templateNames().join(", ")}.`,
|
|
150
|
-
);
|
|
151
|
+
super(`Unknown template "${requested}". Available: ${templateNames().join(", ")}.`);
|
|
151
152
|
this.name = "UnknownTemplateError";
|
|
152
153
|
this.requested = requested;
|
|
153
154
|
}
|
|
@@ -166,9 +167,7 @@ export function templateNames() {
|
|
|
166
167
|
* @returns {string}
|
|
167
168
|
*/
|
|
168
169
|
export function canonicalTemplateName(name) {
|
|
169
|
-
return Object.prototype.hasOwnProperty.call(TEMPLATE_ALIASES, name)
|
|
170
|
-
? TEMPLATE_ALIASES[name]
|
|
171
|
-
: name;
|
|
170
|
+
return Object.prototype.hasOwnProperty.call(TEMPLATE_ALIASES, name) ? TEMPLATE_ALIASES[name] : name;
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-dig-app",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Scaffold a wallet-wired, deployable DIG Network app — free, no mint. The JS front door for building dapps, frontends, and NFT collections on Chia.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "DIG Network",
|
|
@@ -43,9 +43,12 @@
|
|
|
43
43
|
"scripts": {
|
|
44
44
|
"test": "node --test",
|
|
45
45
|
"coverage": "c8 node --test",
|
|
46
|
-
"start": "node bin/create-dig-app.js"
|
|
46
|
+
"start": "node bin/create-dig-app.js",
|
|
47
|
+
"format": "prettier --write .",
|
|
48
|
+
"format:check": "prettier --check ."
|
|
47
49
|
},
|
|
48
50
|
"devDependencies": {
|
|
49
|
-
"c8": "10.1.3"
|
|
51
|
+
"c8": "10.1.3",
|
|
52
|
+
"prettier": "^3.3.3"
|
|
50
53
|
}
|
|
51
54
|
}
|
|
@@ -44,12 +44,12 @@ export default function App() {
|
|
|
44
44
|
<main className="wrap">
|
|
45
45
|
<h1>__DISPLAY_NAME__</h1>
|
|
46
46
|
<p>
|
|
47
|
-
A wallet-wired dapp on the <strong>DIG Network</strong>. Your wallet is your account — no
|
|
48
|
-
|
|
47
|
+
A wallet-wired dapp on the <strong>DIG Network</strong>. Your wallet is your account — no email, no
|
|
48
|
+
password.
|
|
49
49
|
</p>
|
|
50
50
|
<p className="muted">
|
|
51
|
-
Connecting and previewing are <strong>free</strong>. There is no mint, no chain, and no spend
|
|
52
|
-
|
|
51
|
+
Connecting and previewing are <strong>free</strong>. There is no mint, no chain, and no spend here —
|
|
52
|
+
you only spend $DIG when you publish with <code>digstore deploy</code>.
|
|
53
53
|
</p>
|
|
54
54
|
|
|
55
55
|
{address ? (
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
--error: #dc2626;
|
|
7
7
|
|
|
8
8
|
/* DIG brand accent — violet -> magenta (SYSTEM.md visual theme; matches dig.net/hub/status). */
|
|
9
|
-
--dig-violet: #
|
|
10
|
-
--dig-magenta: #
|
|
9
|
+
--dig-violet: #5800d6;
|
|
10
|
+
--dig-magenta: #ff00de;
|
|
11
11
|
--accent: var(--dig-violet);
|
|
12
|
-
--grad-brand: linear-gradient(115deg, #
|
|
12
|
+
--grad-brand: linear-gradient(115deg, #5800d6 0%, #ff00de 100%);
|
|
13
13
|
|
|
14
14
|
/* DIG brand fonts — named first, system stack as the offline/no-fetch fallback so a scaffolded
|
|
15
15
|
capsule never depends on an external font host (keeps the site self-contained + offline-safe). */
|
|
@@ -17,9 +17,15 @@
|
|
|
17
17
|
--dig-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
18
18
|
}
|
|
19
19
|
@media (prefers-color-scheme: dark) {
|
|
20
|
-
:root {
|
|
20
|
+
:root {
|
|
21
|
+
--fg: #e2e8f0;
|
|
22
|
+
--muted: #94a3b8;
|
|
23
|
+
--bg: #0b1120;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
* {
|
|
27
|
+
box-sizing: border-box;
|
|
21
28
|
}
|
|
22
|
-
* { box-sizing: border-box; }
|
|
23
29
|
body {
|
|
24
30
|
margin: 0;
|
|
25
31
|
min-height: 100vh;
|
|
@@ -29,7 +35,10 @@ body {
|
|
|
29
35
|
color: var(--fg);
|
|
30
36
|
background: var(--bg);
|
|
31
37
|
}
|
|
32
|
-
.wrap {
|
|
38
|
+
.wrap {
|
|
39
|
+
max-width: 42rem;
|
|
40
|
+
padding: 2rem;
|
|
41
|
+
}
|
|
33
42
|
h1 {
|
|
34
43
|
font-size: 2.25rem;
|
|
35
44
|
margin: 0 0 0.5rem;
|
|
@@ -39,8 +48,12 @@ h1 {
|
|
|
39
48
|
background-clip: text;
|
|
40
49
|
color: transparent;
|
|
41
50
|
}
|
|
42
|
-
.muted {
|
|
43
|
-
|
|
51
|
+
.muted {
|
|
52
|
+
color: var(--muted);
|
|
53
|
+
}
|
|
54
|
+
.error {
|
|
55
|
+
color: var(--error);
|
|
56
|
+
}
|
|
44
57
|
button {
|
|
45
58
|
font: inherit;
|
|
46
59
|
padding: 0.6rem 1.1rem;
|
|
@@ -50,7 +63,10 @@ button {
|
|
|
50
63
|
color: white;
|
|
51
64
|
cursor: pointer;
|
|
52
65
|
}
|
|
53
|
-
button:disabled {
|
|
66
|
+
button:disabled {
|
|
67
|
+
opacity: 0.6;
|
|
68
|
+
cursor: default;
|
|
69
|
+
}
|
|
54
70
|
.card {
|
|
55
71
|
margin: 1rem 0;
|
|
56
72
|
padding: 1rem;
|
|
@@ -59,8 +75,16 @@ button:disabled { opacity: 0.6; cursor: default; }
|
|
|
59
75
|
display: grid;
|
|
60
76
|
gap: 0.5rem;
|
|
61
77
|
}
|
|
62
|
-
.row {
|
|
63
|
-
|
|
78
|
+
.row {
|
|
79
|
+
display: flex;
|
|
80
|
+
gap: 0.75rem;
|
|
81
|
+
align-items: baseline;
|
|
82
|
+
flex-wrap: wrap;
|
|
83
|
+
}
|
|
84
|
+
code {
|
|
85
|
+
font-family: var(--dig-mono);
|
|
86
|
+
word-break: break-all;
|
|
87
|
+
}
|
|
64
88
|
pre {
|
|
65
89
|
font-family: var(--dig-mono);
|
|
66
90
|
margin-top: 1.5rem;
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
--error: #dc2626;
|
|
7
7
|
|
|
8
8
|
/* DIG brand accent — violet -> magenta (SYSTEM.md visual theme; matches dig.net/hub/status). */
|
|
9
|
-
--dig-violet: #
|
|
10
|
-
--dig-magenta: #
|
|
9
|
+
--dig-violet: #5800d6;
|
|
10
|
+
--dig-magenta: #ff00de;
|
|
11
11
|
--accent: var(--dig-violet);
|
|
12
|
-
--grad-brand: linear-gradient(115deg, #
|
|
12
|
+
--grad-brand: linear-gradient(115deg, #5800d6 0%, #ff00de 100%);
|
|
13
13
|
|
|
14
14
|
/* DIG brand fonts — named first, system stack as the offline/no-fetch fallback so a scaffolded
|
|
15
15
|
capsule never depends on an external font host (keeps the site self-contained + offline-safe). */
|
|
@@ -17,9 +17,15 @@
|
|
|
17
17
|
--dig-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
18
18
|
}
|
|
19
19
|
@media (prefers-color-scheme: dark) {
|
|
20
|
-
:root {
|
|
20
|
+
:root {
|
|
21
|
+
--fg: #e2e8f0;
|
|
22
|
+
--muted: #94a3b8;
|
|
23
|
+
--bg: #0b1120;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
* {
|
|
27
|
+
box-sizing: border-box;
|
|
21
28
|
}
|
|
22
|
-
* { box-sizing: border-box; }
|
|
23
29
|
body {
|
|
24
30
|
margin: 0;
|
|
25
31
|
min-height: 100vh;
|
|
@@ -29,7 +35,10 @@ body {
|
|
|
29
35
|
color: var(--fg);
|
|
30
36
|
background: var(--bg);
|
|
31
37
|
}
|
|
32
|
-
.wrap {
|
|
38
|
+
.wrap {
|
|
39
|
+
max-width: 40rem;
|
|
40
|
+
padding: 2rem;
|
|
41
|
+
}
|
|
33
42
|
h1 {
|
|
34
43
|
font-size: 2.25rem;
|
|
35
44
|
margin: 0 0 0.5rem;
|
|
@@ -39,7 +48,9 @@ h1 {
|
|
|
39
48
|
background-clip: text;
|
|
40
49
|
color: transparent;
|
|
41
50
|
}
|
|
42
|
-
.muted {
|
|
51
|
+
.muted {
|
|
52
|
+
color: var(--muted);
|
|
53
|
+
}
|
|
43
54
|
pre {
|
|
44
55
|
font-family: var(--dig-mono);
|
|
45
56
|
background: rgba(127, 127, 127, 0.12);
|
|
@@ -3,8 +3,8 @@ export default function Home() {
|
|
|
3
3
|
<main className="wrap">
|
|
4
4
|
<h1>__DISPLAY_NAME__</h1>
|
|
5
5
|
<p>
|
|
6
|
-
A Next.js static-export site on the <strong>DIG Network</strong> — served from a network no
|
|
7
|
-
|
|
6
|
+
A Next.js static-export site on the <strong>DIG Network</strong> — served from a network no host can
|
|
7
|
+
read, change, or take down.
|
|
8
8
|
</p>
|
|
9
9
|
<p className="muted">
|
|
10
10
|
Build and preview for <strong>free</strong>. You only spend $DIG when you publish.
|