create-dig-app 0.1.1

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/bin/create-dig-app.js +17 -0
  4. package/lib/cli.js +438 -0
  5. package/lib/index.js +235 -0
  6. package/lib/nft-cli.js +265 -0
  7. package/lib/nft-metadata.js +515 -0
  8. package/lib/substitute.js +47 -0
  9. package/lib/templates.js +185 -0
  10. package/package.json +51 -0
  11. package/templates/dapp-window-chia/README.md +63 -0
  12. package/templates/dapp-window-chia/_env.example +7 -0
  13. package/templates/dapp-window-chia/_gitignore +10 -0
  14. package/templates/dapp-window-chia/dig.toml +17 -0
  15. package/templates/dapp-window-chia/index.html +12 -0
  16. package/templates/dapp-window-chia/package.json +24 -0
  17. package/templates/dapp-window-chia/src/App.jsx +91 -0
  18. package/templates/dapp-window-chia/src/main.jsx +10 -0
  19. package/templates/dapp-window-chia/src/styles.css +71 -0
  20. package/templates/dapp-window-chia/src/wallet.js +47 -0
  21. package/templates/dapp-window-chia/vite.config.js +14 -0
  22. package/templates/next-static/README.md +41 -0
  23. package/templates/next-static/_gitignore +6 -0
  24. package/templates/next-static/app/globals.css +49 -0
  25. package/templates/next-static/app/layout.jsx +14 -0
  26. package/templates/next-static/app/page.jsx +18 -0
  27. package/templates/next-static/dig.toml +17 -0
  28. package/templates/next-static/next.config.mjs +11 -0
  29. package/templates/next-static/package.json +16 -0
  30. package/templates/nft-collection/README.md +119 -0
  31. package/templates/nft-collection/_env.example +5 -0
  32. package/templates/nft-collection/_gitignore +9 -0
  33. package/templates/nft-collection/assets/banner.svg +11 -0
  34. package/templates/nft-collection/assets/icon.svg +10 -0
  35. package/templates/nft-collection/collection.json +14 -0
  36. package/templates/nft-collection/dig.toml +23 -0
  37. package/templates/nft-collection/images/sample-1.svg +5 -0
  38. package/templates/nft-collection/images/sample-2.svg +5 -0
  39. package/templates/nft-collection/licenses/.gitkeep +1 -0
  40. package/templates/nft-collection/metadata/.gitkeep +2 -0
  41. package/templates/nft-collection/package.json +18 -0
  42. package/templates/nft-collection/scripts/dig-nft.mjs +479 -0
  43. package/templates/nft-collection/src/mint.js +72 -0
  44. package/templates/nft-collection/src/styles.css +64 -0
  45. package/templates/nft-collection/traits.csv +3 -0
  46. package/templates/nft-drop/README.md +71 -0
  47. package/templates/nft-drop/_env.example +7 -0
  48. package/templates/nft-drop/_gitignore +10 -0
  49. package/templates/nft-drop/dig.toml +18 -0
  50. package/templates/nft-drop/index.html +12 -0
  51. package/templates/nft-drop/package.json +24 -0
  52. package/templates/nft-drop/src/App.jsx +91 -0
  53. package/templates/nft-drop/src/main.jsx +10 -0
  54. package/templates/nft-drop/src/mint.js +72 -0
  55. package/templates/nft-drop/src/styles.css +70 -0
  56. package/templates/nft-drop/vite.config.js +13 -0
  57. package/templates/static-site/README.md +41 -0
  58. package/templates/static-site/_gitignore +5 -0
  59. package/templates/static-site/dig.toml +19 -0
  60. package/templates/static-site/package.json +10 -0
  61. package/templates/static-site/scripts/build.mjs +14 -0
  62. package/templates/static-site/src/index.html +20 -0
  63. package/templates/static-site/src/styles.css +49 -0
  64. package/templates/vite-react/README.md +42 -0
  65. package/templates/vite-react/_gitignore +5 -0
  66. package/templates/vite-react/dig.toml +17 -0
  67. package/templates/vite-react/index.html +12 -0
  68. package/templates/vite-react/package.json +20 -0
  69. package/templates/vite-react/src/App.jsx +18 -0
  70. package/templates/vite-react/src/main.jsx +10 -0
  71. package/templates/vite-react/src/styles.css +49 -0
  72. package/templates/vite-react/vite.config.js +9 -0
  73. package/templates-ts/dapp-window-chia/README.md +67 -0
  74. package/templates-ts/dapp-window-chia/_env.example +7 -0
  75. package/templates-ts/dapp-window-chia/_gitignore +10 -0
  76. package/templates-ts/dapp-window-chia/dig.toml +17 -0
  77. package/templates-ts/dapp-window-chia/index.html +12 -0
  78. package/templates-ts/dapp-window-chia/package.json +28 -0
  79. package/templates-ts/dapp-window-chia/src/App.tsx +93 -0
  80. package/templates-ts/dapp-window-chia/src/main.tsx +13 -0
  81. package/templates-ts/dapp-window-chia/src/styles.css +71 -0
  82. package/templates-ts/dapp-window-chia/src/vite-env.d.ts +11 -0
  83. package/templates-ts/dapp-window-chia/src/wallet.ts +62 -0
  84. package/templates-ts/dapp-window-chia/tsconfig.json +20 -0
  85. package/templates-ts/dapp-window-chia/vite.config.ts +14 -0
  86. package/templates-ts/next-static/README.md +43 -0
  87. package/templates-ts/next-static/_gitignore +7 -0
  88. package/templates-ts/next-static/app/globals.css +49 -0
  89. package/templates-ts/next-static/app/layout.tsx +16 -0
  90. package/templates-ts/next-static/app/page.tsx +18 -0
  91. package/templates-ts/next-static/dig.toml +17 -0
  92. package/templates-ts/next-static/next-env.d.ts +5 -0
  93. package/templates-ts/next-static/next.config.mjs +11 -0
  94. package/templates-ts/next-static/package.json +23 -0
  95. package/templates-ts/next-static/tsconfig.json +21 -0
  96. package/templates-ts/nft-drop/README.md +74 -0
  97. package/templates-ts/nft-drop/_env.example +7 -0
  98. package/templates-ts/nft-drop/_gitignore +10 -0
  99. package/templates-ts/nft-drop/dig.toml +18 -0
  100. package/templates-ts/nft-drop/index.html +12 -0
  101. package/templates-ts/nft-drop/package.json +28 -0
  102. package/templates-ts/nft-drop/src/App.tsx +93 -0
  103. package/templates-ts/nft-drop/src/main.tsx +13 -0
  104. package/templates-ts/nft-drop/src/mint.ts +86 -0
  105. package/templates-ts/nft-drop/src/styles.css +70 -0
  106. package/templates-ts/nft-drop/src/vite-env.d.ts +11 -0
  107. package/templates-ts/nft-drop/tsconfig.json +20 -0
  108. package/templates-ts/nft-drop/vite.config.ts +13 -0
  109. package/templates-ts/vite-react/README.md +44 -0
  110. package/templates-ts/vite-react/_gitignore +5 -0
  111. package/templates-ts/vite-react/dig.toml +17 -0
  112. package/templates-ts/vite-react/index.html +12 -0
  113. package/templates-ts/vite-react/package.json +24 -0
  114. package/templates-ts/vite-react/src/App.tsx +18 -0
  115. package/templates-ts/vite-react/src/main.tsx +13 -0
  116. package/templates-ts/vite-react/src/styles.css +49 -0
  117. package/templates-ts/vite-react/src/vite-env.d.ts +1 -0
  118. package/templates-ts/vite-react/tsconfig.json +20 -0
  119. package/templates-ts/vite-react/vite.config.ts +9 -0
@@ -0,0 +1,185 @@
1
+ // The template registry — the single source of truth for what `create-dig-app` can scaffold.
2
+ //
3
+ // Each template is a directory under ../templates/<name>/ whose files are copied verbatim except for
4
+ // `__PLACEHOLDER__` token substitution (see substitute.js). The metadata here drives:
5
+ // - the interactive picker + `--template` validation (templateNames / resolveTemplate),
6
+ // - the dig.toml the scaffolder writes (outputDir + buildCommand, which the SDK adapter and
7
+ // `digstore deploy` both read — see modules/dig-sdk/src/adapters/dig-toml.ts),
8
+ // - which templates wire @dignetwork/dig-sdk (wallet) vs stay dependency-light static sites.
9
+ //
10
+ // Templates are kept MINIMAL but real: each one `npm install`s and builds, and none bundles a heavy
11
+ // framework footprint beyond what the framework itself requires.
12
+
13
+ /**
14
+ * @typedef {("js"|"ts")} Lang A scaffold language: plain JavaScript or TypeScript.
15
+ */
16
+
17
+ /**
18
+ * @typedef {Object} TemplateMeta
19
+ * @property {string} name Template id (matches the directory name).
20
+ * @property {string} title Short human title for the picker.
21
+ * @property {string} description One-line description for the picker + `--help`.
22
+ * @property {string} outputDir The built-output dir digstore publishes (written into dig.toml).
23
+ * @property {string} buildCommand Build command digstore runs in CI (written into dig.toml).
24
+ * @property {boolean} wallet True if the template wires @dignetwork/dig-sdk (ChiaProvider).
25
+ * @property {Lang[]} langs Languages this template can be scaffolded in, in offer order.
26
+ * Always includes "js"; includes "ts" when a TypeScript variant
27
+ * exists under ../templates-ts/<name>/ (see {@link resolveLang}).
28
+ */
29
+
30
+ // The default scaffold language. JS stays the default so existing invocations are unchanged.
31
+ export const DEFAULT_LANG = "js";
32
+ /** The languages a user may request, in offer order (also the interactive picker order). */
33
+ export const LANGS = ["js", "ts"];
34
+
35
+ /** @type {Record<string, TemplateMeta>} */
36
+ export const TEMPLATES = {
37
+ // `static-site` has no build step (its "build" just copies src/ → public/), so there is no
38
+ // buildable JS to typecheck and therefore no TypeScript variant — it stays JS-only.
39
+ //
40
+ // Named `static-site` to align with the Rust `digstore new` template id of the same name, so the
41
+ // two front doors (JS `create-dig-app`, Rust `digstore new`) name the same starter identically.
42
+ // The legacy id `static` still works via TEMPLATE_ALIASES (a hidden back-compat alias).
43
+ "static-site": {
44
+ name: "static-site",
45
+ title: "Static site",
46
+ description: "Plain HTML/CSS/JS — zero build step, the lightest way to ship a site on DIG.",
47
+ outputDir: "public",
48
+ buildCommand: "npm run build",
49
+ wallet: false,
50
+ langs: ["js"],
51
+ },
52
+ "vite-react": {
53
+ name: "vite-react",
54
+ title: "Vite + React",
55
+ description: "A React SPA built with Vite — the fast default for an app frontend.",
56
+ outputDir: "dist",
57
+ buildCommand: "npm run build",
58
+ wallet: false,
59
+ langs: ["js", "ts"],
60
+ },
61
+ "next-static": {
62
+ name: "next-static",
63
+ title: "Next.js (static export)",
64
+ description: "Next.js exported to static files (output: 'export') — deployable as a DIG capsule.",
65
+ outputDir: "out",
66
+ buildCommand: "npm run build",
67
+ wallet: false,
68
+ langs: ["js", "ts"],
69
+ },
70
+ "nft-drop": {
71
+ name: "nft-drop",
72
+ title: "NFT drop",
73
+ description: "A wallet-connected NFT mint page, wired to @dignetwork/dig-sdk (no mint at scaffold).",
74
+ outputDir: "dist",
75
+ buildCommand: "npm run build",
76
+ wallet: true,
77
+ langs: ["js", "ts"],
78
+ },
79
+ // The NFT PROJECT starter (richer than nft-drop): a directory-structured collection workspace
80
+ // (images/ assets/ metadata/ licenses/) with dependency-free metadata/license/validate tooling
81
+ // that emits canonical CHIP-0007 metadata + the items.json manifest `digstore collection mint`
82
+ // consumes. JS-only: it is a content/asset workspace driven by Node scripts, not a typed app —
83
+ // there is no buildable app source to typecheck, so (like static-site) it offers no TS variant.
84
+ // `build` runs the validator (a pre-publish gate); the published capsule's content root is the
85
+ // project root (art + metadata + licenses all ship in the capsule).
86
+ "nft-collection": {
87
+ name: "nft-collection",
88
+ title: "NFT collection",
89
+ description: "An NFT collection workspace — art + CHIP-0007 metadata/license tooling for digstore collection mint.",
90
+ outputDir: ".",
91
+ buildCommand: "npm run build",
92
+ wallet: true,
93
+ langs: ["js"],
94
+ },
95
+ "dapp-window-chia": {
96
+ name: "dapp-window-chia",
97
+ title: "Wallet dapp (window.chia)",
98
+ description: "A dapp wired to the injected Chia wallet via ChiaProvider (window.chia → WalletConnect).",
99
+ outputDir: "dist",
100
+ buildCommand: "npm run build",
101
+ wallet: true,
102
+ langs: ["js", "ts"],
103
+ },
104
+ };
105
+
106
+ /**
107
+ * Normalize a user-supplied language token to a canonical {@link Lang}.
108
+ * Accepts the long and short forms: "ts"/"typescript" → "ts", "js"/"javascript" → "js".
109
+ * @param {string} raw
110
+ * @returns {Lang}
111
+ * @throws {Error} on an unrecognized value.
112
+ */
113
+ export function normalizeLang(raw) {
114
+ const v = String(raw ?? "").trim().toLowerCase();
115
+ if (v === "ts" || v === "typescript") return "ts";
116
+ if (v === "js" || v === "javascript") return "js";
117
+ throw new Error(`Unknown --lang "${raw}". Use "js" (javascript) or "ts" (typescript).`);
118
+ }
119
+
120
+ /**
121
+ * Resolve the language a template will actually be scaffolded in: the requested language if the
122
+ * template offers it, otherwise the default ("js"). `static` has no TS variant, so requesting "ts"
123
+ * for it resolves back to "js" (the caller can compare requested vs. resolved to tell the user).
124
+ * @param {TemplateMeta} meta
125
+ * @param {Lang} [requested]
126
+ * @returns {Lang}
127
+ */
128
+ export function resolveLang(meta, requested = DEFAULT_LANG) {
129
+ return meta.langs.includes(requested) ? requested : DEFAULT_LANG;
130
+ }
131
+
132
+ /**
133
+ * Hidden back-compat aliases: legacy/alternate template ids that resolve to a canonical one.
134
+ * Aliases are accepted by {@link resolveTemplate} (so old invocations keep working) but are NOT
135
+ * listed by {@link templateNames} (the picker, `--help`, and `--list-templates` show only the
136
+ * canonical names). Keep this MINIMAL — it exists only to avoid breaking existing scripts.
137
+ * @type {Record<string, string>}
138
+ */
139
+ export const TEMPLATE_ALIASES = {
140
+ // Renamed `static` → `static-site` (2026) to match the Rust `digstore new` template id.
141
+ static: "static-site",
142
+ };
143
+
144
+ /** Raised when a requested template name is not in the registry. */
145
+ export class UnknownTemplateError extends Error {
146
+ /** @param {string} requested */
147
+ constructor(requested) {
148
+ super(
149
+ `Unknown template "${requested}". Available: ${templateNames().join(", ")}.`,
150
+ );
151
+ this.name = "UnknownTemplateError";
152
+ this.requested = requested;
153
+ }
154
+ }
155
+
156
+ /** All canonical template ids, in registry (declaration) order. (Aliases are excluded.) */
157
+ export function templateNames() {
158
+ return Object.keys(TEMPLATES);
159
+ }
160
+
161
+ /**
162
+ * Canonicalize a template id, resolving a hidden alias (e.g. `static` → `static-site`) to its
163
+ * canonical name. Unknown / non-alias names are returned unchanged (and rejected by
164
+ * {@link resolveTemplate}).
165
+ * @param {string} name
166
+ * @returns {string}
167
+ */
168
+ export function canonicalTemplateName(name) {
169
+ return Object.prototype.hasOwnProperty.call(TEMPLATE_ALIASES, name)
170
+ ? TEMPLATE_ALIASES[name]
171
+ : name;
172
+ }
173
+
174
+ /**
175
+ * Resolve a template name (canonical or a hidden alias) to its metadata, or throw
176
+ * {@link UnknownTemplateError}.
177
+ * @param {string} name
178
+ * @returns {TemplateMeta}
179
+ */
180
+ export function resolveTemplate(name) {
181
+ const canonical = name && canonicalTemplateName(name);
182
+ const meta = canonical && TEMPLATES[canonical];
183
+ if (!meta) throw new UnknownTemplateError(name);
184
+ return meta;
185
+ }
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "create-dig-app",
3
+ "version": "0.1.1",
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
+ "license": "MIT",
6
+ "author": "DIG Network",
7
+ "type": "module",
8
+ "bin": {
9
+ "create-dig-app": "bin/create-dig-app.js"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/DIG-Network/create-dig-app"
14
+ },
15
+ "homepage": "https://github.com/DIG-Network/create-dig-app#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/DIG-Network/create-dig-app/issues"
18
+ },
19
+ "keywords": [
20
+ "dig",
21
+ "dig-network",
22
+ "chia",
23
+ "create-dig-app",
24
+ "scaffold",
25
+ "starter",
26
+ "template",
27
+ "dapp",
28
+ "nft",
29
+ "decentralized",
30
+ "wallet"
31
+ ],
32
+ "files": [
33
+ "bin",
34
+ "lib",
35
+ "templates",
36
+ "templates-ts",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "scripts": {
44
+ "test": "node --test test/",
45
+ "coverage": "c8 node --test test/",
46
+ "start": "node bin/create-dig-app.js"
47
+ },
48
+ "devDependencies": {
49
+ "c8": "10.1.3"
50
+ }
51
+ }
@@ -0,0 +1,63 @@
1
+ # __DISPLAY_NAME__
2
+
3
+ A wallet-wired dapp for the **DIG Network** — connects the injected Chia wallet (`window.chia`) via
4
+ `@dignetwork/dig-sdk`'s `ChiaProvider`, with a WalletConnect → Sage fallback.
5
+
6
+ Scaffolded with `npm create dig-app` (template: `dapp-window-chia`).
7
+
8
+ ## Free until publish
9
+
10
+ Scaffolding, building, previewing, and connecting a wallet cost **nothing**. There is **no mint, no
11
+ chain, and no spend** when you create or run this project — you only spend **$DIG** the
12
+ moment you publish a capsule with `digstore deploy`. *Iterate for free, publish when it's ready.*
13
+
14
+ ## How the wallet is wired
15
+
16
+ `src/wallet.js` calls `ChiaProvider.connect({ mode: "auto" })`, which **prefers the injected DIG
17
+ Browser wallet** (`window.chia`) and **falls back to WalletConnect → Sage**. In `digstore dev` an
18
+ injected dev-shim `window.chia` is present, so the connect/read path runs locally — but the shim
19
+ never fakes a signature; open the dapp in the **DIG Browser** (or connect a real wallet) to sign for
20
+ real. See <https://github.com/DIG-Network/dig-sdk> for the full API.
21
+
22
+ ## Connect to Sage in a normal browser (WalletConnect)
23
+
24
+ Outside the DIG Browser there is no injected `window.chia`, so the dapp connects to **Sage** (the
25
+ main Chia wallet) over **WalletConnect**. This needs a free **project id**:
26
+
27
+ 1. Get one at **<https://cloud.reown.com>** (Reown, formerly WalletConnect Cloud).
28
+ 2. Copy `.env.example` to `.env` and set it:
29
+
30
+ ```sh
31
+ cp .env.example .env
32
+ # .env
33
+ VITE_WALLETCONNECT_PROJECT_ID=your_project_id_here
34
+ ```
35
+
36
+ `@walletconnect/sign-client` is already a dependency, so once the project id is set, **Connect
37
+ wallet** shows a pairing link/QR to approve in Sage and then displays your connected address. Leave
38
+ `VITE_WALLETCONNECT_PROJECT_ID` blank to support only the injected DIG Browser wallet. (Never commit
39
+ `.env` — only the placeholder `.env.example` is tracked.)
40
+
41
+ ## Develop
42
+
43
+ ```sh
44
+ npm install
45
+ npm run dev # Vite dev server at http://localhost:5173
46
+ npm run build # production build -> dist/ (your content root)
47
+ digstore dev # preview on the real chia:// read path + dev wallet shim — FREE, no spend
48
+ ```
49
+
50
+ ## Publish (this is the only step that spends $DIG)
51
+
52
+ ```sh
53
+ digstore deploy # build + publish a capsule ($DIG + a small XCH fee)
54
+ ```
55
+
56
+ ## Deploy from CI
57
+
58
+ Wire up push-to-deploy with the GitHub Action:
59
+ <https://docs.dig.net/docs/digstore/cli/deploy-from-github-actions>.
60
+
61
+ ## Config
62
+
63
+ `dig.toml` is the project manifest digstore reads (output dir, build command, default remote).
@@ -0,0 +1,7 @@
1
+ # WalletConnect Cloud / Reown project id — enables the WalletConnect → Sage fallback so this dapp
2
+ # connects to Sage (the main Chia wallet) in a normal browser, not just the DIG Browser.
3
+ #
4
+ # Get a free project id at https://cloud.reown.com (formerly WalletConnect Cloud). Copy this file to
5
+ # `.env` (or `.env.local`) and paste your id. Leave it blank to support ONLY the injected DIG Browser
6
+ # wallet (window.chia) — the app still builds and runs; the WC fallback is just disabled.
7
+ VITE_WALLETCONNECT_PROJECT_ID=
@@ -0,0 +1,10 @@
1
+ node_modules/
2
+ dist/
3
+ .dig/
4
+ .DS_Store
5
+ *.log
6
+
7
+ # Local env (e.g. your WalletConnect projectId) — never commit secrets; .env.example is committed.
8
+ .env
9
+ .env.local
10
+ .env.*.local
@@ -0,0 +1,17 @@
1
+ # dig.toml — the project manifest digstore (and the DIG SDK adapters) read.
2
+ # Keys are kebab-case (snake_case also accepted). See:
3
+ # https://docs.dig.net/docs/digstore/cli/deploy-from-github-actions
4
+ #
5
+ # Everything here is LOCAL config. Scaffolding, building, and `digstore dev` cost nothing —
6
+ # you only spend $DIG when you run `digstore deploy` to publish a capsule.
7
+
8
+ # Vite emits the production build to dist/ — the content root digstore publishes.
9
+ output-dir = "__OUTPUT_DIR__"
10
+
11
+ # The command digstore runs to build before publishing (used by `digstore deploy` / CI).
12
+ build-command = "__BUILD_COMMAND__"
13
+
14
+ # Default remote a `digstore deploy` pushes to (resolves to your store after your first publish).
15
+ remote = "origin"
16
+
17
+ # network = "mainnet"
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>__DISPLAY_NAME__</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.jsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "__APP_NAME__",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "description": "__DISPLAY_NAME__ — a wallet-wired dapp on the DIG Network (window.chia via ChiaProvider).",
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "vite",
9
+ "build": "vite build",
10
+ "preview": "vite preview"
11
+ },
12
+ "dependencies": {
13
+ "@dignetwork/dig-sdk": "__SDK_VERSION__",
14
+ "@walletconnect/sign-client": "^2.11.0",
15
+ "react": "^18.3.1",
16
+ "react-dom": "^18.3.1"
17
+ },
18
+ "devDependencies": {
19
+ "@vitejs/plugin-react": "^4.3.4",
20
+ "vite": "^5.4.11",
21
+ "vite-plugin-top-level-await": "^1.4.4",
22
+ "vite-plugin-wasm": "^3.3.0"
23
+ }
24
+ }
@@ -0,0 +1,91 @@
1
+ import { useState } from "react";
2
+ import { connectWallet } from "./wallet.js";
3
+
4
+ export default function App() {
5
+ const [provider, setProvider] = useState(null);
6
+ const [address, setAddress] = useState("");
7
+ const [error, setError] = useState("");
8
+ const [busy, setBusy] = useState(false);
9
+ // The WalletConnect pairing URI (only set during the WC → Sage fallback). Render it as a copy-link
10
+ // / QR / deep link so the user can approve the connection in Sage.
11
+ const [wcUri, setWcUri] = useState("");
12
+
13
+ async function onConnect() {
14
+ setError("");
15
+ setWcUri("");
16
+ setBusy(true);
17
+ try {
18
+ // Works in both worlds: injected window.chia when present (DIG Browser / extension), otherwise
19
+ // WalletConnect → Sage. `onUri` fires only on the WC path, with the pairing URI to show.
20
+ const p = await connectWallet({ onUri: (uri) => setWcUri(uri) });
21
+ setProvider(p);
22
+ setAddress(await p.getAddress());
23
+ } catch (e) {
24
+ setError(e?.message ?? String(e));
25
+ } finally {
26
+ setBusy(false);
27
+ setWcUri(""); // pairing complete (or failed) — drop the URI
28
+ }
29
+ }
30
+
31
+ async function onSign() {
32
+ setError("");
33
+ try {
34
+ // The dev-shim wallet (in `digstore dev`) does NOT sign — open in the DIG Browser or connect a
35
+ // real wallet (e.g. Sage over WalletConnect) to produce a real signature.
36
+ const { signature } = await provider.signMessage("Login to __DISPLAY_NAME__");
37
+ alert("Signature: " + signature.slice(0, 24) + "…");
38
+ } catch (e) {
39
+ setError(e?.message ?? String(e));
40
+ }
41
+ }
42
+
43
+ return (
44
+ <main className="wrap">
45
+ <h1>__DISPLAY_NAME__</h1>
46
+ <p>
47
+ A wallet-wired dapp on the <strong>DIG Network</strong>. Your wallet is your account — no
48
+ email, no password.
49
+ </p>
50
+ <p className="muted">
51
+ Connecting and previewing are <strong>free</strong>. There is no mint, no chain, and no spend
52
+ here — you only spend $DIG when you publish with <code>digstore deploy</code>.
53
+ </p>
54
+
55
+ {address ? (
56
+ <div className="card">
57
+ <div className="row">
58
+ <span className="muted">Connected via</span>
59
+ <strong>{provider?.backend}</strong>
60
+ </div>
61
+ <div className="row">
62
+ <span className="muted">Address</span>
63
+ <code>{address}</code>
64
+ </div>
65
+ <button onClick={onSign}>Sign a login message</button>
66
+ </div>
67
+ ) : (
68
+ <button onClick={onConnect} disabled={busy}>
69
+ {busy ? "Connecting…" : "Connect wallet"}
70
+ </button>
71
+ )}
72
+
73
+ {wcUri && (
74
+ <div className="card">
75
+ <p className="muted">
76
+ Scan or open this in <strong>Sage</strong> to connect (WalletConnect):
77
+ </p>
78
+ <code>{wcUri}</code>
79
+ <button onClick={() => navigator.clipboard?.writeText(wcUri)}>Copy pairing link</button>
80
+ </div>
81
+ )}
82
+
83
+ {error && <p className="error">{error}</p>}
84
+
85
+ <pre>
86
+ <code>{`digstore dev # preview + dev wallet shim, free
87
+ digstore deploy # publish a capsule ($DIG)`}</code>
88
+ </pre>
89
+ </main>
90
+ );
91
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import App from "./App.jsx";
4
+ import "./styles.css";
5
+
6
+ createRoot(document.getElementById("root")).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>,
10
+ );
@@ -0,0 +1,71 @@
1
+ :root {
2
+ color-scheme: light dark;
3
+ --fg: #0f172a;
4
+ --muted: #64748b;
5
+ --bg: #f8fafc;
6
+ --error: #dc2626;
7
+
8
+ /* DIG brand accent — violet -> magenta (SYSTEM.md visual theme; matches dig.net/hub/status). */
9
+ --dig-violet: #5800D6;
10
+ --dig-magenta: #FF00DE;
11
+ --accent: var(--dig-violet);
12
+ --grad-brand: linear-gradient(115deg, #5800D6 0%, #FF00DE 100%);
13
+
14
+ /* DIG brand fonts — named first, system stack as the offline/no-fetch fallback so a scaffolded
15
+ capsule never depends on an external font host (keeps the site self-contained + offline-safe). */
16
+ --dig-font: "Space Grotesk", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif;
17
+ --dig-mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
18
+ }
19
+ @media (prefers-color-scheme: dark) {
20
+ :root { --fg: #e2e8f0; --muted: #94a3b8; --bg: #0b1120; }
21
+ }
22
+ * { box-sizing: border-box; }
23
+ body {
24
+ margin: 0;
25
+ min-height: 100vh;
26
+ display: grid;
27
+ place-items: center;
28
+ font: 16px/1.6 var(--dig-font);
29
+ color: var(--fg);
30
+ background: var(--bg);
31
+ }
32
+ .wrap { max-width: 42rem; padding: 2rem; }
33
+ h1 {
34
+ font-size: 2.25rem;
35
+ margin: 0 0 0.5rem;
36
+ font-weight: 700;
37
+ background: var(--grad-brand);
38
+ -webkit-background-clip: text;
39
+ background-clip: text;
40
+ color: transparent;
41
+ }
42
+ .muted { color: var(--muted); }
43
+ .error { color: var(--error); }
44
+ button {
45
+ font: inherit;
46
+ padding: 0.6rem 1.1rem;
47
+ border: 0;
48
+ border-radius: 0.5rem;
49
+ background: var(--grad-brand);
50
+ color: white;
51
+ cursor: pointer;
52
+ }
53
+ button:disabled { opacity: 0.6; cursor: default; }
54
+ .card {
55
+ margin: 1rem 0;
56
+ padding: 1rem;
57
+ border-radius: 0.75rem;
58
+ background: rgba(127, 127, 127, 0.12);
59
+ display: grid;
60
+ gap: 0.5rem;
61
+ }
62
+ .row { display: flex; gap: 0.75rem; align-items: baseline; flex-wrap: wrap; }
63
+ code { font-family: var(--dig-mono); word-break: break-all; }
64
+ pre {
65
+ font-family: var(--dig-mono);
66
+ margin-top: 1.5rem;
67
+ background: rgba(127, 127, 127, 0.12);
68
+ padding: 1rem;
69
+ border-radius: 0.5rem;
70
+ overflow-x: auto;
71
+ }
@@ -0,0 +1,47 @@
1
+ // Wallet wiring via @dignetwork/dig-sdk.
2
+ //
3
+ // ChiaProvider gives this dapp a Chia wallet for free: it PREFERS the injected DIG Browser wallet
4
+ // (window.chia) and falls back to WalletConnect → Sage (the main Chia wallet) so the dapp connects
5
+ // in a normal browser too. In `digstore dev` an injected dev-shim window.chia is present, so the
6
+ // connect/read path runs end-to-end locally (read methods only — the shim never fakes a signature).
7
+ // See https://github.com/DIG-Network/dig-sdk for the full API.
8
+
9
+ import { ChiaProvider } from "@dignetwork/dig-sdk";
10
+
11
+ // WalletConnect Cloud / Reown project id, read from the build-time env (see .env.example). When set,
12
+ // it enables the WalletConnect → Sage fallback for browsers without the injected DIG wallet. Get a
13
+ // free project id at https://cloud.reown.com (formerly WalletConnect Cloud).
14
+ const WALLETCONNECT_PROJECT_ID = import.meta.env.VITE_WALLETCONNECT_PROJECT_ID ?? "";
15
+
16
+ /**
17
+ * Connect a wallet. `mode: "auto"` prefers the injected DIG Browser wallet (window.chia) and falls
18
+ * back to WalletConnect → Sage when a project id is configured. The SDK drives its
19
+ * `WalletConnectTransport` under the hood (CHIP-0002 over the relay) — we never hand-roll WC.
20
+ *
21
+ * @param {{ onUri?: (uri: string) => void }} [hooks] `onUri` receives the WalletConnect pairing URI
22
+ * so the UI can render a QR / copy-link / deep link to Sage during the fallback.
23
+ * @returns {Promise<import("@dignetwork/dig-sdk").ChiaProvider>}
24
+ */
25
+ export async function connectWallet(hooks = {}) {
26
+ return ChiaProvider.connect({
27
+ mode: "auto", // prefer injected window.chia; fall back to WalletConnect → Sage if configured
28
+ chain: "chia:mainnet", // CAIP-2 chain the SDK expects (Chia mainnet)
29
+ walletConnect: WALLETCONNECT_PROJECT_ID
30
+ ? {
31
+ projectId: WALLETCONNECT_PROJECT_ID,
32
+ metadata: {
33
+ name: "__DISPLAY_NAME__",
34
+ description: "Built with create-dig-app + @dignetwork/dig-sdk",
35
+ url: typeof window !== "undefined" ? window.location.origin : "https://example.on.dig.net",
36
+ icons: [],
37
+ },
38
+ onUri: hooks.onUri, // render this URI as a QR / copy-link for the Sage fallback
39
+ }
40
+ : undefined,
41
+ });
42
+ }
43
+
44
+ /** True when the WalletConnect → Sage fallback is configured (a project id is set). */
45
+ export function isWalletConnectConfigured() {
46
+ return Boolean(WALLETCONNECT_PROJECT_ID);
47
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import wasm from "vite-plugin-wasm";
4
+ import topLevelAwait from "vite-plugin-top-level-await";
5
+
6
+ // The SDK transitively loads the CHIP-0035 spend builder (@dignetwork/dig-sdk →
7
+ // chip35-dl-coin-wasm), a WebAssembly module with top-level await, so we enable the wasm +
8
+ // top-level-await plugins. Relative base so the built dapp works from any path on a
9
+ // *.on.dig.net subdomain (and chia://).
10
+ export default defineConfig({
11
+ base: "./",
12
+ plugins: [react(), wasm(), topLevelAwait()],
13
+ build: { outDir: "dist" },
14
+ });
@@ -0,0 +1,41 @@
1
+ # __DISPLAY_NAME__
2
+
3
+ A Next.js static-export site for the **DIG Network** — deployed to a network no host can read,
4
+ change, or take down.
5
+
6
+ Scaffolded with `npm create dig-app` (template: `next-static`).
7
+
8
+ > This template uses `output: 'export'` (`next.config.mjs`). A DIG capsule is a **blind static
9
+ > host** — there is no Next.js server at runtime, so use static-export-compatible features only.
10
+
11
+ ## Free until publish
12
+
13
+ Scaffolding, building, and previewing cost **nothing**. There is **no mint, no chain, and no spend**
14
+ when you create or run this project — you only spend **$DIG** the moment you publish a
15
+ capsule with `digstore deploy`. *Iterate for free, publish when it's ready.*
16
+
17
+ ## Develop
18
+
19
+ ```sh
20
+ npm install
21
+ npm run dev # Next dev server at http://localhost:3000
22
+ npm run build # static export -> out/ (your content root)
23
+ digstore dev # preview on the real chia:// read path — FREE, no chain, no spend
24
+ ```
25
+
26
+ ## Publish (this is the only step that spends $DIG)
27
+
28
+ ```sh
29
+ digstore deploy # build + publish a capsule ($DIG + a small XCH fee)
30
+ ```
31
+
32
+ Your site goes live at its `*.on.dig.net` address. Re-run `digstore deploy` to ship an update.
33
+
34
+ ## Deploy from CI
35
+
36
+ Wire up push-to-deploy with the GitHub Action:
37
+ <https://docs.dig.net/docs/digstore/cli/deploy-from-github-actions>.
38
+
39
+ ## Config
40
+
41
+ `dig.toml` is the project manifest digstore reads (output dir, build command, default remote).
@@ -0,0 +1,6 @@
1
+ node_modules/
2
+ .next/
3
+ out/
4
+ .dig/
5
+ .DS_Store
6
+ *.log