Skip to main content
Next.js 15 + React 18 + Tailwind + Jotai + @stacks/connect v8 + @stacks/transactions v7. After stacksdapp generate and stacksdapp deploy, the frontend calls deployed contracts via reusable generated hooks.

Contents

Full-stack checklist

Keep <DebugContracts /> on the home page while building. It validates hooks work before you ship custom UI.

Architecture

Rule: Never edit generated/*. Build custom UI in components/ and import from @/generated/hooks.

Generated hooks

Each public/read-only function gets one hook in frontend/src/generated/hooks.ts: Naming: use + {ContractPascalCase} + _ + {FunctionPascalCase}.

Hook return values

deployments.json

Contract calls resolve addresses from frontend/src/generated/deployments.json:
  • Written by stacksdapp deploy
  • If missing, calls log a warning and return undefined
  • After redeploy with auto-versioning (counter-v2), run stacksdapp generate if bindings drift

Network config

Driven by frontend/.env.local:
stacksdapp dev --network testnet updates .env.local automatically. Import scaffoldConfig from @/scaffold.config for network, nodeUrl, isDevnet, isTestnet, and getReadOnlyNetwork().

Signing model

Do not expect Leather/Xverse to sign devnet writes. Devnet uses template burner mnemonics from contracts/settings/Devnet.toml.
Never reuse devnet burner mnemonics on testnet or mainnet.

Using hooks

Read-only hooks resolve on call() — no txid polling. Public hooks poll the node until success or abort.
SIP-010 / SIP-009 hooks follow the same pattern. See SIP standards.

Parsing read-only data

Read-only hooks return cvToValue output, not plain JavaScript numbers. SIP-010 get-balance typically returns:
Wrong (throws Cannot convert [object Object] to a BigInt):
Right — unwrap first:
SIP-010 amounts are base units. Divide by 10**decimals for human display.

Failed to fetch errors

TypeError: Failed to fetch on read-only calls means the HTTP request to the node failed — not a Clarity revert. Agent rule: After stacksdapp deploy --network testnet, run stacksdapp dev --network testnet (not bare stacksdapp dev which defaults to devnet). Pre-flight:
More fixes: Troubleshooting

Building Clarity arguments

Use Cl from @stacks/transactions: Check the generated debug UI or contract ABI for exact field names.

Wallet integration

User must connect Leather or Xverse on testnet/mainnet before public calls from custom UI.

Custom UI workflow

  1. Edit contracts → stacksdapp check && stacksdapp generate && stacksdapp test
  2. Deploy → stacksdapp deploy --network testnet --yes
  3. Create component in frontend/src/components/ with "use client" and hook imports
  4. Add to app/page.tsx or a new route
  5. Run stacksdapp dev --network testnet
For direct (non-hook) calls in scripts:
Prefer hooks in React components for loading/error/tx state.

Common mistakes

Live reload

  • stacksdapp dev (devnet): file watcher regenerates bindings on .clar changes
  • stacksdapp dev --network testnet: run stacksdapp generate --watch in a second terminal
  • After regenerate, refresh hook imports in your components