-
Notifications
You must be signed in to change notification settings - Fork 6
feat: add dashmint-lab example app #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
1e231e6
chore: import dashmint-lab as example app
thephez d3f3c3d
chore: integrate dashmint-lab with host repo tooling
thephez 685df57
test: add vitest suite for dashmint-lab helpers
thephez dd9580e
chore(dashmint-lab): add prettier and format app
thephez 557f91e
fix: make header height stable
thephez 0d12cec
fix: tighten typed boundaries and mutation feedback
thephez 5659d7f
test(dashmint-lab): add vitest coverage for app, session, and modals
thephez e59bb69
test(dashmint-lab): cover CardTile actions and mint-screen gating
thephez 8b0e6e5
style: run npm format
thephez 91b4b6a
feat(dashmint-lab): accept DPNS names as transfer recipients
thephez 30a28e1
refactor(dashmint-lab): extract MAX_QUERY_LIMIT constant
thephez 9702835
feat(dashmint-lab): link card owner to Platform Explorer
thephez 112ce4c
feat(dashmint-lab): show signed-in credit balance in heading
thephez 3419450
feat(dashmint-lab): randomize starter pack from shared card pool
thephez d4e370e
ci(dashmint-lab): add GitHub Pages deploy workflow with fork-friendly…
thephez 140643c
feat(ui): replace placeholder card art with deterministic SVG themes
thephez 180d052
refactor(dashmint-lab): remove unused fetchBalance helper and test
thephez a962752
chore: npm format
thephez 7fbde7b
docs: update readme and claude file
thephez 6711310
style: update favicon
thephez a83e394
fix(dashmint-lab): prevent concurrent mint operations on the same ide…
thephez eee5fc1
fix(dashmint-lab): give Modal proper dialog semantics and focus manag…
thephez 6c5bcc2
fix(dashmint-lab): reset PurchaseModal state when reopened
thephez af69f3a
fix(dashmint-lab): reject dotted recipient inputs with disallowed chars
thephez 9934666
fix(dashmint-lab): throw when contract publish returns no id
thephez f53ec2d
fix(dashmint-lab): close DPNS cache race in concurrent hook instances
thephez 4aeadb0
fix(dashmint-lab): don't cache transient DPNS lookup errors as not-found
thephez 28de79c
style(dashmint-lab): collapse contractId assignment onto one line
thephez 9ab168b
docs: clarify root tsconfig scope and example-apps boundary
thephez 35d3907
fix(dashmint-lab): trim recipient input in useResolvedRecipient
thephez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| example-apps/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| name: Deploy DashMint Lab to GitHub Pages | ||
|
|
||
| # Manual-only trigger so forks never auto-publish. Forkers must (1) enable | ||
| # Pages with source "GitHub Actions" in repo Settings, then (2) run this | ||
| # workflow from the Actions tab. Deploys to: | ||
| # https://<owner>.github.io/<repo>/dashmint-lab/ | ||
| # The base path is derived from github.event.repository.name, so a fork | ||
| # works with zero config changes. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pages: write | ||
| id-token: write | ||
|
|
||
| concurrency: | ||
| group: pages-dashmint-lab | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
|
|
||
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | ||
| with: | ||
| node-version: 20 | ||
| cache: npm | ||
| cache-dependency-path: example-apps/dashmint-lab/package-lock.json | ||
|
|
||
| - name: Install | ||
| run: npm ci | ||
| working-directory: example-apps/dashmint-lab | ||
|
|
||
| - name: Build | ||
| run: npm run build | ||
| working-directory: example-apps/dashmint-lab | ||
| env: | ||
| # Self-configuring base path: resolves to /<repo>/dashmint-lab/ | ||
| # on any fork without editing the workflow. | ||
| VITE_BASE_PATH: /${{ github.event.repository.name }}/dashmint-lab/ | ||
|
|
||
| - name: Assemble site | ||
| run: | | ||
| mkdir -p _site/dashmint-lab | ||
| cp -r example-apps/dashmint-lab/dist/. _site/dashmint-lab/ | ||
|
|
||
| - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 | ||
| with: | ||
| path: _site | ||
|
|
||
| deploy: | ||
| needs: build | ||
| runs-on: ubuntu-latest | ||
| environment: | ||
| name: github-pages | ||
| url: ${{ steps.deployment.outputs.page_url }} | ||
| steps: | ||
| - id: deployment | ||
| uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| example-apps/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Example Apps | ||
|
|
||
| Stand-alone applications built on top of the same `@dashevo/evo-sdk` used by the Node tutorials in the parent repo. Each example is an independent npm project — `cd` into its directory and run `npm install` there. | ||
|
|
||
| ## Apps | ||
|
|
||
| - [dashmint-lab/](./dashmint-lab/) — React + TypeScript + Vite SPA for minting, viewing, transferring, and trading NFT-style collectible cards on Dash Platform testnet. Shares the browser-safe SDK core (`setupDashClient-core.mjs`) with the Node tutorials at the repo root. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| pnpm-debug.log* | ||
| lerna-debug.log* | ||
|
|
||
| node_modules | ||
| dist | ||
| dist-ssr | ||
| *.local | ||
|
|
||
| # Editor directories and files | ||
| .vscode/* | ||
| !.vscode/extensions.json | ||
| .idea | ||
| .DS_Store | ||
| *.suo | ||
| *.ntvs* | ||
| *.njsproj | ||
| *.sln | ||
| *.sw? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| dist | ||
| node_modules | ||
| coverage |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # DashMint Lab — Dash Platform NFTs (Modern React) | ||
|
|
||
| React + TypeScript + Vite app for minting, viewing, transferring, and trading NFT-style collectible cards on Dash Platform testnet. Ships with browse-only mode, DPNS-aware recipient input, a themed SVG card-art layer, and a deterministic starter pack. | ||
|
|
||
| ## Commands | ||
|
|
||
| - `npm run dev` — start Vite dev server | ||
| - `npm run build` — typecheck (`tsc -b`) then bundle | ||
| - `npm run lint` — ESLint | ||
| - `npm run test` — Vitest suite in [test/](test/) | ||
| - `npm run format` / `format:check` — Prettier | ||
| - `npm run preview` — serve production build locally | ||
|
|
||
| ## Architecture | ||
|
|
||
| - **[src/dash/](src/dash/)** — one file per Platform SDK operation. Each exports an async function with a leading JSDoc block. No hooks, no wrappers — the SDK call is the function. Includes the `classifyRecipientInput` / `resolveRecipient` DPNS helpers. | ||
| - **Shared SDK core** — [src/dash/client.ts](src/dash/client.ts) and [src/dash/keyManager.ts](src/dash/keyManager.ts) re-export directly from `../../../../setupDashClient-core.mjs` (the canonical browser-safe core at the host repo root). No vendoring, no backport step. The `@dashevo/evo-sdk` bare specifier is aliased to the app's local copy via [vite.config.ts](vite.config.ts). | ||
| - **[src/session/](src/session/)** — `SessionContext.tsx` provides the context (SDK, keyManager, identityId, contractId, contractOwnerId, balance, activity log) and calls `sdk.identities.balance` inline; `useSession.ts` is the consumer hook. Mnemonic lives only in the keyManager closure — never in state, never in localStorage. | ||
| - **[src/components/](src/components/)** — standard React. Modals call `src/dash/` functions directly. Notable: [HowItWorks.tsx](src/components/HowItWorks.tsx) (static education tab), [CardArt.tsx](src/components/CardArt.tsx) (deterministic themed SVG), [OddsTable.tsx](src/components/OddsTable.tsx). | ||
| - **[src/hooks/](src/hooks/)** — `useDpnsName` (identityId → username) and `useResolvedRecipient` (name → identityId). Both use module-level caches so repeated renders don't re-query. | ||
| - **[src/data/starterPack.ts](src/data/starterPack.ts)** — shared card pool and `drawStarterPack()` Fisher-Yates shuffle. Injectable RNG for deterministic tests. | ||
| - **[src/lib/](src/lib/)** — pure utilities: [rarity.ts](src/lib/rarity.ts) (tier from atk+def), [format.ts](src/lib/format.ts), [explorer.ts](src/lib/explorer.ts) (Platform Explorer URLs), [cardArt.ts](src/lib/cardArt.ts) (theme/palette recipe — presentation only, not Platform-relevant). | ||
| - **[src/styles/globals.css](src/styles/globals.css)** — Tailwind v4 import + rarity tokens. | ||
| - **[test/](test/)** — Vitest + Testing Library. All test files live here per the `include` pattern in [vite.config.ts](vite.config.ts) and are named after the subject under test (e.g. `CardTile.test.tsx`, `SessionContext.test.tsx`). Default env is `node`; tests that need DOM opt in with `// @vitest-environment jsdom`. | ||
|
|
||
| ## SDK Patterns | ||
|
|
||
| - **Minting**: `sdk.documents.create({ document, identityKey, signer })` | ||
| - **Transfer**: `sdk.documents.transfer({ document, recipientId, identityKey, signer })` | ||
| - **Set price**: `sdk.documents.setPrice({ document, price: BigInt, identityKey, signer })` | ||
| - **Purchase**: `sdk.documents.purchase({ document, buyerId, price: BigInt, identityKey, signer })` | ||
| - **Burn**: `sdk.documents.delete({ document: { id, ownerId, dataContractId, documentTypeName }, identityKey, signer })` | ||
| - **Query**: `sdk.documents.query({ dataContractId, documentTypeName, where?, limit })` | ||
| - **DPNS resolve**: `sdk.dpns.resolveName(fullName)` / `sdk.dpns.username(identityId)` | ||
| - **Balance**: `sdk.identities.balance(identityId)` → `bigint` (called directly from `SessionContext`) | ||
|
|
||
| All mutations except mint flow through [withAuthedCard.ts](src/dash/withAuthedCard.ts), which fetches the document, bumps its revision, and resolves the auth signer. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - All document mutations (transfer, setPrice, purchase) require fetching the document first and incrementing `document.revision = BigInt(document.revision) + 1n` | ||
| - Transfer/trade operations use AUTHENTICATION keys, not TRANSFER purpose keys — the SDK rejects TRANSFER purpose for these state transitions | ||
| - Attack/defense are randomly generated (1–10) on mint; rarity is derived client-side in [rarity.ts](src/lib/rarity.ts) (common ≤10, rare 11–14, legendary ≥15) and is not persisted | ||
| - Browse-only mode sets `keyManager` to null — `withAuthedCard` guards this; check session status before any write operation | ||
| - `listMarketplaceCards` filters client-side for `$price` (no server-side trade-mode index available yet) | ||
| - DPNS names are normalized to lowercase + `.dash` suffix before resolving; `classifyRecipientInput` distinguishes identity IDs from names by character set, not length | ||
| - Contract ID stored in `localStorage['dashmint-lab.contractId']` (public, safe to persist); clearing falls back to `DEFAULT_CONTRACT_ID` in [contract.ts](src/dash/contract.ts) so browse-only mode always has something queryable | ||
| - The mint tab is gated to the contract owner — non-owners see an informative overlay | ||
| - The Evo SDK WASM bundle is ~8MB; this is expected and not a build error | ||
| - `allowJs: true` in tsconfig so TypeScript can import the JSDoc-typed `.mjs` core at the host repo root | ||
| - Deploys to GitHub Pages via `VITE_BASE_PATH`; the workflow lives at the repo root under `.github/workflows/` | ||
| - [src/lib/cardArt.ts](src/lib/cardArt.ts) and [src/components/CardArt.tsx](src/components/CardArt.tsx) are presentation-only — don't mistake them for contract or document logic |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| # DashMint Lab — Dash Platform NFTs (Modern React) | ||
|
|
||
| A React + TypeScript + Vite app demonstrating every Dash Platform NFT operation: mint, transfer, price, purchase, burn, and query. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Node >= 20 (developed on v20.19.5, npm 10.8.2) | ||
| - A funded Dash Platform testnet identity (BIP-39 mnemonic + identity index) | ||
| - (Optional) A second funded identity for testing cross-profile transfer and purchase | ||
| - Browse-only mode works without any identity — visitors can explore the marketplace | ||
|
|
||
| ## Quick start | ||
|
|
||
| ```bash | ||
| npm install | ||
| npm run dev | ||
| ``` | ||
|
|
||
| Production build: `npm run build && npm run preview` | ||
|
|
||
| Other scripts: | ||
|
|
||
| ```bash | ||
| npm run test # Vitest suite | ||
| npm run lint # ESLint | ||
| npm run format # Prettier (write) | ||
| npm run format:check # Prettier (check only) | ||
| ``` | ||
|
|
||
| ## Known constraints | ||
|
|
||
| - The app is built for Dash Platform testnet, not mainnet. | ||
| - Write operations require a funded Platform identity; browse-only mode works without login. | ||
| - Trading flows are easiest to test with a second funded identity. | ||
| - The active contract ID can be swapped or a new one can be registered from Settings. | ||
| - Minting is restricted to the contract owner by the schema (`creationRestrictionMode: 1`); non-owners see an overlay on the Mint tab. | ||
| - The browser bundle is intentionally heavy because it includes the full `@dashevo/evo-sdk` (~8MB WASM). | ||
|
|
||
| ## Platform operations at a glance | ||
|
|
||
| Every SDK call lives in its own file under [`src/dash/`](src/dash/). Open the file to see the full implementation with a JSDoc header explaining what it does and why. | ||
|
|
||
| | Operation | File | SDK method | | ||
| | -------------------- | -------------------------------------------------------------- | ------------------------------------------- | | ||
| | Connect to testnet | [`src/dash/client.ts`](src/dash/client.ts) | `EvoSDK.testnetTrusted()` + `sdk.connect()` | | ||
| | Derive identity keys | [`src/dash/keyManager.ts`](src/dash/keyManager.ts) | `wallet.deriveKeyFromSeedWithPath` | | ||
| | Deploy card contract | [`src/dash/contract.ts`](src/dash/contract.ts) | `sdk.contracts.publish` | | ||
| | Mint a card | [`src/dash/mintCard.ts`](src/dash/mintCard.ts) | `sdk.documents.create` | | ||
| | Transfer a card | [`src/dash/transferCard.ts`](src/dash/transferCard.ts) | `sdk.documents.transfer` | | ||
| | Set / remove price | [`src/dash/setPrice.ts`](src/dash/setPrice.ts) | `sdk.documents.setPrice` | | ||
| | Purchase a card | [`src/dash/purchaseCard.ts`](src/dash/purchaseCard.ts) | `sdk.documents.purchase` | | ||
| | Burn (delete) a card | [`src/dash/burnCard.ts`](src/dash/burnCard.ts) | `sdk.documents.delete` | | ||
| | Query cards | [`src/dash/queries.ts`](src/dash/queries.ts) | `sdk.documents.query` | | ||
| | Resolve DPNS name | [`src/dash/resolveRecipient.ts`](src/dash/resolveRecipient.ts) | `sdk.dpns.resolveName` | | ||
|
|
||
| Balance is fetched inline from `SessionContext` via `sdk.identities.balance(identityId)` — it's a one-liner, so there's no dedicated `src/dash/` file for it. | ||
|
|
||
| Supporting files: | ||
|
|
||
| - **[`src/dash/withAuthedCard.ts`](src/dash/withAuthedCard.ts)** — shared mutation prelude used by transfer, setPrice, purchase, and burn. Fetches the document, bumps its revision, and resolves the authentication signer. | ||
| - **[`src/dash/classifyRecipientInput.ts`](src/dash/classifyRecipientInput.ts)** — decides whether a recipient string looks like a DPNS name or an identity ID by character set. | ||
| - **[`src/dash/logger.ts`](src/dash/logger.ts)** — shared `Logger` type so every operation can stream progress messages to the UI. | ||
|
|
||
| ## Reading this codebase | ||
|
|
||
| Recommended order for understanding how the app works: | ||
|
|
||
| 1. **[`src/dash/`](src/dash/)** — start here. One file per Platform operation, each with a JSDoc block explaining what / why / which SDK method. Read [`mintCard.ts`](src/dash/mintCard.ts) first (simplest create flow), then [`withAuthedCard.ts`](src/dash/withAuthedCard.ts) (shared pattern for mutations that need the current document). | ||
|
|
||
| 2. **[`src/session/SessionContext.tsx`](src/session/SessionContext.tsx)** — manages the SDK connection, identity, contract ID, contract-owner ID, credit balance, and activity log. The mnemonic never enters React state; it lives only inside the `keyManager` closure and is garbage-collected on logout. The consumer hook lives in [`useSession.ts`](src/session/useSession.ts). | ||
|
|
||
| 3. **[`src/components/`](src/components/)** — standard React UI. [`CardTile.tsx`](src/components/CardTile.tsx) renders a single card with rarity rail, owner chip, and action buttons. Modals wire directly to the `src/dash/` functions. [`HowItWorks.tsx`](src/components/HowItWorks.tsx) is the in-app education tab. | ||
|
|
||
| 4. **[`src/hooks/`](src/hooks/)** — [`useDpnsName`](src/hooks/useDpnsName.ts) resolves an identity ID to a DPNS username for display; [`useResolvedRecipient`](src/hooks/useResolvedRecipient.ts) does the reverse for the transfer modal. Both cache across component mounts so lists of cards don't re-query. | ||
|
|
||
| 5. **[`src/data/starterPack.ts`](src/data/starterPack.ts)** — the shared card pool and `drawStarterPack()` helper behind the "Mint Starter Pack" button. | ||
|
|
||
| 6. **[`src/lib/`](src/lib/)** — pure utilities. [`rarity.ts`](src/lib/rarity.ts) maps attack + defense to a rarity tier (common / rare / legendary). [`format.ts`](src/lib/format.ts) truncates IDs and formats credits. [`explorer.ts`](src/lib/explorer.ts) builds Platform Explorer URLs. [`cardArt.ts`](src/lib/cardArt.ts) derives a deterministic theme, palette, and composition from each card's name/description/stats — it's presentation-only and has nothing to do with the on-chain schema. | ||
|
|
||
| ## Tests | ||
|
|
||
| [`test/`](test/) uses Vitest + Testing Library, co-located by subject. The default Vitest environment is Node; component tests opt into jsdom per-file with `// @vitest-environment jsdom`. Run with `npm run test`. | ||
|
|
||
| ## Deploying to GitHub Pages | ||
|
|
||
| The project ships with a fork-friendly deploy workflow at the repo root. Pushing the deploy branch triggers a Vite build with `VITE_BASE_PATH` set to the repo name so links resolve under `/<repo>/`. For local previews of that build, run: | ||
|
|
||
| ```bash | ||
| VITE_BASE_PATH=/dashmint-lab/ npm run build && npm run preview | ||
| ``` | ||
|
|
||
| ## Tech stack | ||
|
|
||
| - React 19 | ||
| - TypeScript | ||
| - Vite 8 | ||
| - Tailwind CSS v4 | ||
| - Vitest 4 + Testing Library | ||
| - `@dashevo/evo-sdk` | ||
| - sonner (toasts) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import js from "@eslint/js"; | ||
| import globals from "globals"; | ||
| import reactHooks from "eslint-plugin-react-hooks"; | ||
| import reactRefresh from "eslint-plugin-react-refresh"; | ||
| import tseslint from "typescript-eslint"; | ||
| import { defineConfig, globalIgnores } from "eslint/config"; | ||
|
|
||
| export default defineConfig([ | ||
| globalIgnores(["dist"]), | ||
| { | ||
| files: ["**/*.{ts,tsx}"], | ||
| extends: [ | ||
| js.configs.recommended, | ||
| tseslint.configs.recommended, | ||
| reactHooks.configs.flat.recommended, | ||
| reactRefresh.configs.vite, | ||
| ], | ||
|
thephez marked this conversation as resolved.
|
||
| languageOptions: { | ||
| ecmaVersion: 2020, | ||
| globals: globals.browser, | ||
| }, | ||
| }, | ||
| ]); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>DashMint Lab — Dash Platform NFTs</title> | ||
| </head> | ||
| <body> | ||
| <div id="root"></div> | ||
| <script type="module" src="/src/main.tsx"></script> | ||
| </body> | ||
| </html> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.