Note: This guide is for developers who want to contribute to Wallet Gateway. It is worth reading the entire doc first before starting setup.
- Node.js 24+ (see
.nvmrcfor exact version) - pnpm (version specified in
package.json#packageManager) - Java (for Canton) - sdkman is recommended for version management
An unofficial, community-contributed nix shell is available as well to provide these system dependencies.
-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.7/install.sh | bash # or curl -fsSL https://fnm.vercel.app/install | bash
-
Restart your terminal
-
Run
nvm installorfnm installto install the Node.js version from.nvmrc -
Install pnpm
curl -fsSL https://get.pnpm.io/install.sh | sh - -
Run
pnpm installto install dependencies -
Run
pnpm postinstallto set up auto sign-off hooks
In order for Husky to use the correct node version (as part of our pre-commit), you might need to add an init file for certain IDEs.
Create the file ~/.config/husky/init.sh with the following content:
# ~/.config/husky/init.sh
# for nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
# or
# for fnm
eval "$(fnm env)"As a requirement under the Hyperledger Foundation, all commits must be signed off. This can be done by adding the -s flag every time you commit.
In this repo, we use Husky to automatically configure a git hook to do this for you.
It is also recommended (but not required) to add a GPG key: https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account
We use conventional commits to track version changes for packages and create informative changelogs. Our linter automatically checks that the commit scope matches an nx project name. Some common commit types are:
feat-- results in a minor version bump for the scoped package (feat(pkg): ...)fix-- results in a patch version bump for the scoped package (fix(pkg): ...)build,chore,ci,docs,perf,refactor,revert,style,test
Major version bumps are triggered by adding an exclamation after the scope (feat(pkg)!: breaking change) or by including a BREAKING CHANGE: ... trailer at the end of the commit message.
Build all packages:
pnpm build:allThis uses nx to build all workspaces in parallel. After the initial build, you can selectively build each package by navigating into the corresponding directory and running pnpm build.
Other useful commands:
pnpm clean:all # Clean all build artifacts and reset nx cache
pnpm test:all # Run tests across all packages
pnpm full:rebuild # Clean, regenerate, and rebuild everything
pnpm full:up # Start localnet and all dev servers
pnpm full:down # Stop everything and rebuildRun pnpm generate:<api> from the root to regenerate RPC clients/servers. For example:
pnpm generate:dapp # Regenerate dApp API client
pnpm generate:all # Regenerate all API specsTo support fast iteration loops, most workspaces have dev scripts that watch their source directories for changes and rebuild. Start all dev servers with:
pnpm start:allThis uses pm2 to run each dev server in parallel. See the pm2 cheatsheet for more commands (preface them with pnpm pm2 when invoking).
pnpm pm2 list # Show running processes
pnpm pm2 logs # View logs
pnpm stop:all # Stop all servicesNote: Codegenned artifacts are not automatically watched. Use
pnpm generate:allif updating the API specs.
After running pnpm start:all, you'll have services exposed on the following ports:
| Service | URL |
|---|---|
| Example Ping dApp | localhost:8080 |
| Example Portfolio | localhost:8081 |
| HTTP Wallet Gateway | localhost:3030 |
To run a local Splice network (includes Canton + Splice services):
pnpm script:fetch:localnet # Download localnet artifacts
pnpm start:localnet # Start the local network
pnpm stop:localnet # Stop the local networkIf you need to run Canton without the full Splice network (localnet already includes Canton):
- Ensure you have Java installed - sdkman is recommended for version management
- Run
pnpm script:fetch:cantonto download Canton to.canton/ - Run
pnpm start:cantonto start a participant & synchronizer
pnpm start:canton # Start Canton (mainnet config)
pnpm start:canton:tls # Start Canton with TLS enabled
pnpm start:canton:console # Start Canton with interactive consoleMany scripts support a --network flag to target different environments:
pnpm script:fetch:canton --network=devnet # Fetch devnet Canton version
pnpm script:fetch:canton --network=mainnet # Fetch mainnet Canton version (default)If you've cloned this repository when it was set up to use yarn, finalize the switch to pnpm:
- Pull latest main into your fork / branch
- Stop all running services:
yarn pm2 kill(andyarn stop:localnet, if applicable) - Delete any residual
yarndirectories:rm -rf .pnp.cjs .pnp.loader.mjs .yarn - Run
pnpm install - Done! For 99% of cases, you can now use
pnpmas a direct replacement foryarn, i.e.:yarn build:all-->pnpm build:allyarn start:all-->pnpm start:allyarn pm2 list-->pnpm pm2 list- ... etc
If you've cloned this repository when it was set up to use corepack, finalize the switch to native pnpm:
- Pull latest main into your fork / branch
- Delete any residual
pnpm over corepackreferences:corepack disable pnpm(see pnpm troubleshooting) - Ensure you have at least pnpm 11 installed globally
- Use
pnpm