Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ayushn2/canton_validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

14 Commits

Repository files navigation

Canton Validator

This repository contains:

  1. A running Canton / Splice validator deployed via Docker on an AWS EC2 instance.
  2. A Go client that programmatically interacts with the validator wallet APIs (transactions, balance, etc.).
  3. SSH port-forwarding configuration for secure local access.
  4. JWT-based authentication for protected API access.

1. Architecture Overview

Components

  • AWS EC2 instance running Ubuntu
  • Docker + docker-compose
  • Splice Validator container
  • Wallet API exposed internally on port 5003
  • External UI exposed via port 8080
  • Go client running locally on Mac

Flow

  1. Validator runs inside Docker on EC2.
  2. Wallet API runs inside container (port 5003).
  3. We do NOT expose 5003 publicly.
  4. We use SSH port forwarding to securely access it from local machine.
  5. Go client connects to forwarded localhost port.
  6. All requests require a valid JWT token.

This ensures:

  • No public exposure of wallet API
  • Authenticated access only
  • Controlled access through SSH

Ledger API vs Wallet API (Important Distinction)

There are two different APIs exposed by the validator setup:

1 Ledger API (gRPC - Port 5001)

  • Accessed using grpcurl
  • Used for:
    • Party creation
    • User creation
    • Granting act_as rights
    • Submitting commands (e.g., WalletAppInstall)
    • Querying active contracts
    • Reading ledger updates
  • Service namespace: com.daml.ledger.api.v2.*

This is the low-level Canton Ledger API.


2 Wallet API (REST - Port 5003)

  • Accessed using HTTP requests
  • Base path: http://localhost:5003/api/validator/v0/
  • Used for:
    • Listing wallet transactions
    • Getting wallet balance

This is a higher-level application API built on top of the ledger.


Important:

  • Port 5001 - Ledger (gRPC)
  • Port 5003 - Wallet (REST)

They serve different purposes and require separate SSH port forwarding if accessed remotely.


5. SSH Port Forwarding (Security Layer)

We DO NOT expose port 5003 publicly.

Instead, we use:

ssh -i ~/Downloads/scopex_canton.pem \
-L 5003:localhost:5003 \
ubuntu@ec2-<public-ip>.compute.amazonaws.com

This creates:

Local machine - localhost:5003
Tunnel - EC2 container:5003

Meaning:

  • Only your machine can access wallet API
  • No public attack surface
  • Production-safe approach

Generic Multi-Port SSH Tunnel Example

If you need access to multiple internal services (Ledger gRPC, Wallet API, Wallet UI, ANS UI), you can forward multiple ports in one command:

ssh -i ~/path/to/key.pem \
-L 5001:localhost:5001 \
-L 5003:localhost:5003 \
-L 8080:wallet.localhost:80 \
-L 8081:ans.localhost:80 \
ubuntu@<EC2_PUBLIC_IP>

What this does:

  • -L 5001:localhost:5001 - Forwards Ledger gRPC API
  • -L 5003:localhost:5003 - Forwards Wallet REST API
  • -L 8080:wallet.localhost:80 - Forwards Wallet Web UI
  • -L 8081:ans.localhost:80 - Forwards ANS Web UI

Flow:

Local Machine - SSH Tunnel - EC2 - Docker Container - Internal Service

This keeps all internal services private while allowing secure local access for development.


2. Docker Validator Setup

Validator runs inside:

canton-validator/splice-node/docker-compose/validator

Key commands used:

Start validator:

./start.sh -s "https://sv.sv-1.test.global.canton.network.sync.global" -o "" -p "scopex-validator-1" -m "1" -w

We verified container:

docker ps
docker exec -it splice-validator-validator-1 sh

Important environment variables inside container:

SPLICE_APP_VALIDATOR_WALLET_USER_NAME=administrator
SPLICE_APP_VALIDATOR_LEDGER_API_AUTH_USER_NAME=ledger-api-user

This tells us which user the wallet API expects for authentication.


3. JWT Authentication

We generate token using:

python3 get-token.py administrator

Important:

  • The username MUST match the wallet user inside container (administrator)
  • Otherwise: Authorization Failed

JWT is then passed in header:

Authorization: Bearer <token>

4. Wallet API Endpoints Used

Base path (internal):

http://localhost:5003/api/validator/v0/

List Transactions

POST request:

/wallet/transactions

Body:

{
"page_size": 20
}

Get Balance

GET request:

/wallet/balance

Response includes:

  • effective_unlocked_qty
  • effective_locked_qty
  • round
  • total_holding_fees

6. Go Client Implementation

Located in:

cmd/

Client responsibilities:

  • Create HTTP client with timeout
  • Inject JWT into Authorization header
  • Call:
    • ListTransactions(ctx, pageSize)
    • GetBalance(ctx)
  • Print structured response

Example main flow:

client, _ := cantonvalidator.NewCantonClient()

client.ListTransactions(ctx, 20)
client.GetBalance(ctx)

7. Security Model

Current Security:

  • Wallet API not publicly exposed
  • JWT authentication required
  • Access only via SSH tunnel
  • Token tied to wallet user

If additional security required:

  • Rotate signing secret
  • Restrict EC2 security group to known IP
  • Disable public port 8080
  • Add reverse proxy with TLS

8. What We Achieved

Deployed Canton validator via Docker
Identified correct wallet user
Fixed Authorization errors
Determined required request body schema
Secured API using SSH tunnel
Built Go client for programmatic control
Fetched transactions successfully
Fetched validator wallet balance

System is now:

  • Secure
  • Scriptable
  • Production-ready for automation
  • Extendable for transfers and validator control

9. Next Possible Extensions

  • Add transfer execution in Go
  • Add structured response parsing instead of map[string]interface{}
  • Add CLI flags
  • Add metrics
  • Add background sync loop
  • Add unit tests
  • Add structured logging

10. Final Notes

Never expose port 5003 publicly.

Always use SSH tunnel or private networking.

JWT must match wallet user configured inside container.

This repository now serves as:

  • Validator control client
  • Operational documentation
  • Security reference for deployment

About

Canton/Splice validator deployment on AWS with secure gRPC + REST integration and automated wallet management in Go.

Topics

Resources

Readme

Stars

Watchers

Forks

Releases

No releases published

Packages