The Transaction Tool backend is responsible for facilitating the process by which a transaction is required to be signed by multiple users. This includes creating, sharing, collecting signatures, preparing for submission, and executing the transactions to the specified network.
Personal User Mode: You do not need to set up your local backend to use the application in personal mode. Personal mode allows you to create, sign and submit transactions that requires one user to sign.
Organizational User Mode: The Transaction Tool application can be used without setting up the backend in personal mode. The backend is not required if you are not developing features in the Organization flow. To setup the frontend application, Follow the complete setup process below..
-
-
Required version:
>= 24.19.0 <25 -
Verify installation:
node -v
-
-
-
Required version:
>= 9.13.1 -
Installation of
pnpm(if not already installed):npm install -g pnpm@latest
-
Verify installation:
pnpm --version
-
-
-
Required version:
>= 75.6.0 -
Installation of
python-setuptoolswithbrew:brew install python-setuptools
-
Verify installation:
python -m setuptools --version
-
-
Redis 7.0+
- Required for IP-based rate limiting on sensitive endpoints. The
IpResetPasswordUniqueEmailGuarduses theEXPIRE ... NXcommand introduced in Redis 7.0. Earlier versions will silently skip the expiry, causing rate limit keys to persist indefinitely.
- Required for IP-based rate limiting on sensitive endpoints. The
-
Docker Desktop with Kubernetes enabled
- Enable Kubernetes: Docker Desktop → Settings → Kubernetes → Enable Kubernetes → Apply & Restart.
git clone https://github.com/hashgraph/hedera-transaction-tool.git
cd hedera-transaction-toolThe repository is a single pnpm workspace, so dependencies are installed from the root once for all modules (back-end, front-end, automation):
pnpm installBack-end-specific scripts can then be run via the workspace filter (from any directory). pnpm matches against the name field in package.json; the back-end's NestJS apps are scoped (@back-end/api, @back-end/chain, @back-end/notifications), and -F matches the un-scoped tail:
pnpm -F back-end <script> # e.g. pnpm -F back-end build:all
pnpm -F api test:cov # resolves to @back-end/api
pnpm -F chain test:cov # resolves to @back-end/chain
pnpm -F notifications test:cov # resolves to @back-end/notificationsOr by cd back-end and running the script as before — both work.
Create .env files from the provided example.env templates in each of the following directories:
apps/apiapps/chainapps/notificationstypeormscripts- the root one
The default values work for development.
An email api account enables you to set-up the notification system in the application. You will need to create a free tier Brevo account, or another provider of your choosing.
Note: some providers require no username and password, such as Gmail's smtp-relay service. These values, therefore, are optional.
Example: Create Brevo Account:
- Create a free tier Brevo account
- Log in to your account.
- Select the drop down menu in the top-right corner (next to the notifications icon).
- Select Settings from the dropdown menu.
- In the left sidebar under Organization settings, select SMTP & API.
- Locate your SMTP key in the SMTP keys table.
- (Optional) If no SMTP key appears, select Generate a new SMTP Key in the top-right corner.
- Copy the SMTP key value and add it to your
apps/notifications/.env:
EMAIL_API_HOST=smtp-relay.brevo.com
EMAIL_API_PORT=587
EMAIL_API_SECURE=false
EMAIL_API_USERNAME=<your Brevo login email>
EMAIL_API_PASSWORD=<your SMTP key from step 6>
SENDER_EMAIL=no-reply@<yourdomain.com>
Use the base compose file for CI-style container runs, and add the dev overlay when you want source bind mounts and a
persisted local Postgres data directory. Run from the back-end/ directory — the compose files use context: .. so the build context resolves to the repository root:
docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up --build(First time only) Create email-api-secret.yaml from the example template:
- Navigate to
backend/k8s/dev/ - Copy
email-api-secret.example.yamltoemail-api-secret.yaml - Update the file with your Brevo (or other provider) credentials from step 4.
Ensure Kubernetes cluster is running (Docker Desktop with Kubernetes enabled).
HTTPS Mode Setup (Preferred)
(First time only) Create self-signed certificates for HTTPS. Required for testing with the built Electron client application.
-
Install mkcert (macOS example):
brew install mkcert
-
Create cert directory (if it doesn't exist):
mkdir -p cert
-
Generate certificates:
mkcert -install mkcert -key-file ./cert/key.pem -cert-file ./cert/cert.pem localhost
You can deploy using either the automated script (preferred) or manual steps.
Option 1: Automated Deployment (Preferred)
pnpm deploy:dev
# or
./deploy.shOption 2: Manual Deployment
-
(First time only) Create Kubernetes secret for self-signed certificate:
kubectl create secret tls self-signed-certificate --cert=./cert/cert.pem --key=./cert/key.pem
-
(On backend changes only) Build Docker images from the repository root (the build context is the root, so the workspace lockfile and shared package manifests are visible):
# API service docker build -t back-end-api:1.0.0 -f back-end/apps/api/Dockerfile . # Chain service docker build -t back-end-chain:1.0.0 -f back-end/apps/chain/Dockerfile . # Notifications service docker build -t back-end-notifications:1.0.0 -f back-end/apps/notifications/Dockerfile .
-
Apply deployments (from
back-end/):kubectl apply -f ./k8s/dev/deployments
-
Install Ingress Controller:
helm repo add traefik https://helm.traefik.io/traefik helm repo update helm install traefik traefik/traefik
-
Apply Ingress configuration:
kubectl apply -f ./k8s/dev/ingress.yaml
-
Expose PostgreSQL service:
kubectl port-forward svc/postgres 5432:5432
Exposed Endpoints:
All ports are defined in the docker-compose.yaml file.
The default ports are:
| Type | Endpoint |
|---|---|
| API Service Endpoint | https://localhost |
| Notifications Service Endpoint | https://localhost/notifications |
| PgAdmin | https://localhost:5050 |
To stop all services:
kubectl delete --all deployments,ingresses
helm uninstall traefikTo add the local organization to your application for development:
Ensure your local database is running, then create an admin user:
cd backend/scripts
pnpm create-adminFollow the prompts to:
- Enter an email address (can be any email).
- Enter a password (can be any password).
- Go to the Transaction Tool application.
- Select Add an organization.
- Enter a name for your local organization.
- Enter the local server URL:
https://localhost
Tests are run separately for each service. Navigate to the service you want to test and run the test commands:
API
cd apps/api
pnpm test:cov
Notifications
cd apps/notifications
pnpm test:cov
Chain
cd apps/chain
pnpm test:cov
-
If you encounter setup problems:
- Delete the
node_modulesfolder in thefrontendorbackendor both directories. Reinstallnode_moduleswithpnpm install. - Delete the
pgdatafolder found in thebackenddirectory. Rundocker compose --build. - Verify you are connected to your local development backend to observe the deployed changes and not your staging backend.
- Delete the
-
When installing
traefik, if you receiveError: INSTALLATION FAILED: cannot re-use a name that is still in use:helm upgrade traefik traefik/traefik
-
Docker Image Pull Errors
If you encounter Cloudflare storage connection errors:
error pulling image configuration: download failed after attempts=6:
dialing docker-images-prod.6aa30f8b08e16409b46e0173d6de2f56.r2.cloudflarestorage.com:443
Solution: Use DockerHub Mirror
-
Pull from mirror registry:
docker pull mirror.gcr.io/library/node:24.19.0-alpine
-
Tag the image:
docker tag mirror.gcr.io/library/node:24.19.0-alpine node:24.19.0-alpine
Alternative: Configure Docker Desktop Registry Mirrors:
- Open Docker Desktop → Settings → Docker Engine.
- Add registry mirror configuration:
{ "registry-mirrors": [ "https://your-mirror-url/" ] } - Click Apply & Restart.