The fastest way to build a decentralized application on Canton Network.
- Wallet Connection — Connect/disconnect with status management
- Contract Management — Create, query, exercise, and archive contracts
- Demo Mode — Develop without a Canton node (in-memory ledger simulation)
- Type-Safe — Full TypeScript types for Canton parties, contracts, and templates
- React Hook —
useCanton()hook for wallet + ledger interaction - CIP-103 Ready — Swap the demo provider for
@canton-network/dapp-sdkin production
# Clone
git clone https://github.com/alexandre-mrt/canton-dapp-starter.git
cd canton-dapp-starter
# Install
bun install
# Run in demo mode (no Canton node needed)
bun run devOpen http://localhost:3000 and click "Connect Wallet (Demo Mode)".
┌─────────────────────────┐
│ Your dApp (Next.js) │
│ │
│ useCanton() hook │
│ ├── connect() │
│ ├── query() │
│ ├── create() │
│ └── exercise() │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Canton Provider │
│ │
│ DemoCantonProvider │ ← Development (in-memory)
│ JsonApiCantonProvider │ ← Production (JSON API v2)
│ @canton-network/dapp-sdk │ ← Production (CIP-103)
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Canton Network │
│ (Participant Node) │
└─────────────────────────┘
import { useCanton } from "@/hooks/use-canton";
function MyComponent() {
const { status, account, connect, disconnect, query, create, exercise } = useCanton();
// Connect wallet
const handleConnect = async () => {
const account = await connect();
console.log("Connected as", account.partyId);
};
// Query contracts
const contracts = await query("#my-app:Main:Asset", { owner: account.partyId });
// Create contract
const contractId = await create("#my-app:Main:Asset", {
issuer: account.partyId,
owner: account.partyId,
name: "My Token",
amount: "1000.0",
});
// Exercise choice
await exercise("#my-app:Main:Asset", contractId, "Transfer", {
newOwner: "Bob::abc123",
});
}Replace DemoCantonProvider with the real JSON API provider:
// In src/lib/canton-provider.ts
import { JsonApiCantonProvider } from "./canton-provider";
const provider = new JsonApiCantonProvider(
{ jsonApiUrl: "http://localhost:7575", network: "local" },
"your-jwt-token"
);Or use the official Canton dApp SDK for CIP-103 wallet integration:
bun add @canton-network/dapp-sdksrc/
types/canton.ts # Canton type definitions
lib/canton-provider.ts # Provider implementations (demo + real)
hooks/use-canton.ts # React hook for Canton interaction
components/
wallet-button.tsx # Wallet connect/disconnect
contract-list.tsx # Contract display and management
create-contract.tsx # Contract creation form
app/
page.tsx # Main page
layout.tsx # Root layout
globals.css # Styles
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_JSON_API_URL |
Canton JSON Ledger API | http://localhost:7575 |
| Package | Purpose |
|---|---|
@canton-network/dapp-sdk |
Browser SDK for dApps (CIP-103) |
@canton-network/wallet-sdk |
Node SDK for wallets/exchanges |
This project targets the Canton Foundation Grants Program:
- Category: Developer Tools
- Focus: Accelerating dApp development on Canton Network
MIT