Skip to content

Repository files navigation

Canton dApp Booster

Local Canton Network stack for wallet-first dApp experiments.

flowchart TD
fe["dapp/frontend<br/>dApp frontend<br/>http://localhost:3012"]
wallet["carpincho-wallet<br/>Vault + signer<br/>http://localhost:3011"]
ws["canton-barebones/wallet-service<br/>External-party bridge<br/>http://localhost:3010"]
au["Splice app-user<br/>primary local validator<br/>JSON API http://localhost:2975"]
sv["Splice sv<br/>SV / DSO / synchronizer side"]
scan["Scan<br/>Splice read model<br/>http://scan.localhost:4000"]
dar["dapp/daml<br/>quickstart-tally DAR"]
fe <-->|"Injected CIP-0103 provider<br/>optional WalletConnect"| wallet
wallet -->|"external-party onboarding"| ws
wallet -->|"Scan API / token metadata"| scan
ws -->|"Bearer CANTON_BACKEND_TOKEN"| au
au <--> sv
sv -->|"indexed Splice read model"| scan
dar -->|"deploy package"| au
Loading

canton:up activates the official Splice LocalNet sv and app-user Docker profiles, then starts wallet-service. It does not start Keycloak or OIDC. The app-provider UI containers are not started; a local compose override disables their Nginx routes. The official shared Canton/Splice containers still expose app-provider backend ports because the bundle bakes that config in. Splice and wallet-service share the canton-barebones Docker Compose project, so Docker groups the full local stack together. app-user is Splice's technical name for the primary local validator; it is not the Carpincho user.

Installation

Prerequisites:

  • Node.js 24
  • npm >=7
  • Docker with about 8 GB memory available
  • dpm on PATH (DAML SDK 3.4.11), required for building DARs

Install workspace dependencies:

npm install

Create the local env file:

cp canton-barebones/.env.example canton-barebones/.env

Generate the backend token and paste the printed CANTON_BACKEND_TOKEN=... line into canton-barebones/.env:

npm run canton:token -- ledger-api-user

Token configuration:

NameWhat It IsWho Uses It
CANTON_AUTH_AUDIENCEJWT audience recipe valuetoken script
CANTON_AUTH_SECRETlocal unsafe JWT signing secrettoken script only
CANTON_BACKEND_TOKENgenerated JWT pasted into .envwallet-service
Carpincho LocalNet tokengenerated JWT pasted into Carpincho settingsCarpincho

The token script uses ledger-api-user as the default JWT subject. Generate another token with the same script or reuse the backend token locally. Do not copy CANTON_AUTH_SECRET into Carpincho.

Optional WalletConnect fallback:

cp carpincho-wallet/.env.local.example carpincho-wallet/.env.local
cp dapp/frontend/.env.local.example dapp/frontend/.env.local

Set VITE_WC_PROJECT_ID in both files only if you use WalletConnect.

Quick Start

Start the stack:

npm run canton:up
npm run canton:health

Build and deploy the sample DAR:

npm run build-dar -- dapp/daml
npm run deploy-dar -- dapp/daml/.daml/dist/quickstart-tally-0.0.1.dar

Verify wallet-service:

npm run wallet-service:health

Start Carpincho and the dApp:

npm run wallet:dev
npm run app:dev

Open the dApp:

http://localhost:3012

In the frontend:

  1. Keep canton:localnet in settings.
  2. Click Connect with Carpincho.
  3. Approve the request in Carpincho.

Extension

Build the extension:

npm run carpincho:build:extension

Load carpincho-wallet/dist-extension from chrome://extensions with Developer mode enabled.

Services And Ports

ServiceWhat It IsURL / PortWho Uses It
wallet-serviceCarpincho bridge for external-party onboardinghttp://localhost:3010Carpincho
Carpincho walletBrowser wallet UI/providerhttp://localhost:3011user/dApp
dApp frontendExample dApphttp://localhost:3012user
app-user Wallet UIOfficial Splice wallet UI for app-userhttp://wallet.localhost:2000optional/manual
app-user Ledger APIgRPC Ledger APIgrpc://localhost:2901SDK/tools
app-user Admin APIgRPC Admin APIgrpc://localhost:2902wallet-service/tools
app-user Validator APISplice validator readiness/APIhttp://localhost:2903health/tools
app-user JSON APIJSON Ledger APIhttp://localhost:2975wallet-service/tools
app-user Validator proxywallet-sdk validator routehttp://localhost:2000/api/validatorCarpincho
app-provider backend APIsOfficial bundle backend wiring, unused heregrpc://localhost:3901, grpc://localhost:3902, http://localhost:3903, http://localhost:3975not used
app-provider UI portNginx port exposed by the bundle; routes disabled herehttp://localhost:3000not used
Scan UISplice explorer/read model UIhttp://scan.localhost:4000optional/manual
Scan APISplice indexed APIhttp://scan.localhost:4000/api/scanCarpincho/tools
Amulet Registrytoken metadata via scan proxyhttp://localhost:2000/api/validator/v0/scan-proxyCarpincho/tools
SV UISuper Validator operations UIhttp://sv.localhost:4000optional/manual
sv Ledger/Admin/JSON APIsOfficial SV participant APIsgrpc://localhost:4901, grpc://localhost:4902, http://localhost:4975Splice internals/tools
sv Validator APISV readiness/admin surfacehttp://localhost:4903health checks
PostgreSQLSplice LocalNet DBlocalhost:5432LocalNet containers/tools

If wallet.localhost, scan.localhost, or sv.localhost do not resolve, add:

127.0.0.1 wallet.localhost scan.localhost sv.localhost

Releasing

The root package.jsonversion is the single source of truth for the release. Publishing a GitHub Release builds and publishes the artifacts.

  1. Bump the version and tag it from the repo root:

    npm version <x.y.z>

    This updates the root package.json, commits, and creates the v<x.y.z> tag.

  2. Push the commit and tag:

    git push --follow-tags
  3. Publish a GitHub Release for that tag (the GitHub UI, or gh release create v<x.y.z>).