Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Shared libraries used by the Wallet Gateway, SDKs, and signing providers:
| `core-signing-participant` | [`core/signing-participant`](core/signing-participant) | Canton participant-managed signing driver |
| `core-signing-fireblocks` | [`core/signing-fireblocks`](core/signing-fireblocks) | Fireblocks signing driver integration |
| `core-signing-blockdaemon` | [`core/signing-blockdaemon`](core/signing-blockdaemon) | Blockdaemon signing driver integration |
| `core-signing-securosys` | [`core/signing-securosys`](core/signing-securosys) | Securosys TSB signing driver integration |
| **RPC & Transport** | | |
| `core-types` | [`core/types`](core/types) | Shared types and transport-agnostic parsers |
| `core-rpc-transport` | [`core/rpc-transport`](core/rpc-transport) | RPC transport implementations |
Expand Down
1 change: 1 addition & 0 deletions core/signing-lib/src/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum SigningProvider {
FIREBLOCKS = 'fireblocks',
BLOCKDAEMON = 'blockdaemon',
DFNS = 'dfns',
SECUROSYS = 'securosys',
}

// Generic signing driver configuration schema
Expand Down
262 changes: 262 additions & 0 deletions core/signing-securosys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
# @canton-network/core-signing-securosys

Signing driver for integrating the Canton Wallet Gateway with Securosys TSB.

## Features

- `createKey` creates a TSB SKA key with a hardcoded empty policy.
- `getKeys` enumerates TSB keys and returns Wallet Gateway-compatible public
keys.
- `signTransaction` creates a TSB sign request and returns the TSB request ID as
the provider `txId`.
- `getTransaction` maps TSB request status/result into Wallet Gateway
transaction status/signature fields.
- `getTransactions` fetches by provider transaction IDs. Public-key-only
filtering is supported from this driver's in-memory transaction cache.
- Runtime configuration can be inspected and changed through
`getConfiguration` / `setConfiguration`.

## Usage

```typescript
import SecurosysSigningDriver from '@canton-network/core-signing-securosys'

const driver = new SecurosysSigningDriver({
baseUrl: 'http://localhost:8080',
keyManagementApiKey: process.env.TSB_KEY_MANAGEMENT_API_KEY,
keyOperationApiKey: process.env.TSB_KEY_OPERATION_API_KEY,
mtlsP12Path: process.env.TSB_MTLS_P12_PATH,
mtlsP12Password: process.env.TSB_MTLS_P12_PASSWORD,
})
```

The TSB endpoints used by the driver are:

- `GET /v1/key`
- `POST /v1/key`
- `POST /v1/key/attributes`
- `POST /v1/sign`
- `GET /v1/request/{id}`
- `POST /v1/filteredRequests`
- `DELETE /v1/request/{id}`

## Configuration

| Property | Description |
| :-- | :-- |
| `baseUrl` | Base URL of the TSB service. |
| `keyManagementApiKey` | `X-API-KEY` value for `/v1/key` endpoints. |
| `keyOperationApiKey` | `X-API-KEY` value for signing/request-status endpoints. |
| `bearerToken` | Optional bearer access token for access-token mode. |
| `mtlsP12Path` | Optional path to a PKCS#12/P12 client certificate used when TSB requires mTLS. |
| `mtlsP12Password` | Optional password for the PKCS#12/P12 client certificate. |
| `keyPassword` | Optional TSB key password used for key attributes and signing. |
| `signatureAlgorithm` | TSB signature algorithm. Defaults to `EDDSA`; current Wallet Gateway/Canton signing expects Ed25519-compatible signatures. |

When these values are changed through the Wallet Gateway configuration RPC, use
the existing PascalCase convention: `MtlsP12Path` and `MtlsP12Password`.
`MtlsP12Password` is masked in `getConfiguration`.

The remote Wallet Gateway reads the same values from these environment
variables:

| Environment variable | Driver property |
| :-- | :-- |
| `SECUROSYS_TSB_BASE_URL` | `baseUrl` |
| `SECUROSYS_TSB_KEY_MANAGEMENT_API_KEY` | `keyManagementApiKey` |
| `SECUROSYS_TSB_KEY_OPERATION_API_KEY` | `keyOperationApiKey` |
| `SECUROSYS_TSB_BEARER_TOKEN` | `bearerToken` |
| `SECUROSYS_TSB_MTLS_P12_PATH` | `mtlsP12Path` |
| `SECUROSYS_TSB_MTLS_P12_PASSWORD` | `mtlsP12Password` |
| `SECUROSYS_TSB_KEY_PASSWORD` | `keyPassword` |
| `SECUROSYS_TSB_SIGNATURE_ALGORITHM` | `signatureAlgorithm` |

Every key created by this driver is sent to TSB with the same empty SKA policy:

```json
{
"ruleUse": null,
"ruleBlock": null,
"ruleUnblock": null,
"ruleModify": null,
"keyStatus": {
"blocked": false
}
}
```

For EdDSA signatures, the driver validates and returns the Wallet
Gateway-compatible format: base64-encoded raw 64-byte Ed25519 signature bytes.
The TSB request payload type is hardcoded to `UNSPECIFIED`, the signature type
is hardcoded to `RAW`, and TSB Ed25519 DER/SPKI public keys are always converted
to the 32-byte raw key expected by the wallet signing API. Simple ASN.1 OCTET
STRING / BIT STRING wrappers and DER `R,S` sequences are still converted as a
compatibility guard before returning the signature.

## Local wallet deployment

Run the wallet monorepo commands from the wallet repository root:

```bash
cd /path/to/wallet
```

Use Node.js 20+ for the wallet toolchain.
Install Yarn 4 and the wallet dependencies:

```bash
npm install -g --force @yarnpkg/cli-dist@4.16.0
yarn install
```

Download the Playwright browsers required by the wallet browser tests:

```bash
yarn playwright:install
```

Download the Canton binary used by the local devnet setup:

```bash
yarn script:fetch:canton
```

Start local Canton on the devnet configuration:

```bash
yarn start:canton --network=devnet
```

Wait until the Canton bootstrap completes. The command can then be interrupted
with `Ctrl+C`; the Canton process keeps running under PM2.

Start the full wallet stack with Securosys mTLS:

```bash
SECUROSYS_TSB_BASE_URL=https://integration-test.cloudshsm.com/ \
SECUROSYS_TSB_MTLS_P12_PATH=./etc/client_mtls_tsb.p12 \
SECUROSYS_TSB_MTLS_P12_PASSWORD=pass \
yarn start:all
```

Start the full wallet stack with a TSB bearer token instead:

```bash
SECUROSYS_TSB_BASE_URL=https://sbx-rest-api.cloudshsm.com \
SECUROSYS_TSB_BEARER_TOKEN="<JWT Token>" \
yarn start:all
```

Open the Wallet Gateway UI:

```bash
open http://localhost:3030
```

Check gateway health and readiness:

```bash
curl -i http://localhost:3030/healthz
curl -i http://localhost:3030/readyz
```

## Process management

List all PM2-managed wallet processes:

```bash
yarn pm2 list
```

Inspect the remote Wallet Gateway logs:

```bash
yarn pm2 logs remote
```

Inspect the Canton logs:

```bash
yarn pm2 logs canton
```

Restart only the remote Wallet Gateway backend:

```bash
yarn pm2 restart remote
```

Stop all PM2-managed wallet processes:

```bash
yarn stop:all
```

Fully kill the PM2 daemon and all managed processes:

```bash
yarn pm2 kill
```

## Build and test

Build only this signing driver:

```bash
yarn workspace @canton-network/core-signing-securosys build
```

Run only this signing driver's tests:

```bash
yarn workspace @canton-network/core-signing-securosys test
```

Run this signing driver's tests with coverage:

```bash
yarn workspace @canton-network/core-signing-securosys test:coverage
```

Build the remote Wallet Gateway:

```bash
yarn workspace @canton-network/wallet-gateway-remote build
```

Run the remote Wallet Gateway transaction-signing tests:

```bash
yarn workspace @canton-network/wallet-gateway-remote test src/ledger/transaction-service.test.ts
```

Run the wallet allocation tests:

```bash
yarn workspace @canton-network/wallet-gateway-remote test src/ledger/wallet-allocation/wallet-allocation-service.test.ts
```

Run the shared signing-library tests:

```bash
yarn workspace @canton-network/core-signing-lib test
```

Build the full wallet monorepo serially:

```bash
yarn build:all:serial
```

Run the full wallet monorepo test suite:

```bash
yarn test:all
```

## References

- Upstream signing interface:
<https://github.com/canton-network/wallet/tree/main/core/signing-lib>
- Blockdaemon signing driver used as the implementation reference:
<https://github.com/canton-network/wallet/tree/main/core/signing-blockdaemon>
51 changes: 51 additions & 0 deletions core/signing-securosys/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@canton-network/core-signing-securosys",
"version": "0.1.0",
"type": "module",
"description": "Wallet Gateway signing driver for Securosys TSB",
"license": "Apache-2.0",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
}
},
"scripts": {
"build": "tsup --onSuccess \"tsc\"",
"clean": "rm -rf ./dist ./coverage",
"test": "vitest run --project node",
"test:coverage": "vitest run --project node --coverage"
},
"dependencies": {
"@canton-network/core-signing-lib": "workspace:^",
"@canton-network/core-wallet-auth": "workspace:^",
"undici": "^7.24.5"
},
"devDependencies": {
"@types/node": "^25.9.4",
"@vitest/coverage-v8": "^4.1.10",
"tsup": "^8.5.1",
"typescript": "^5.9.3",
"vitest": "^4.1.10"
},
"files": [
"dist/**"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/canton-network/wallet.git",
"directory": "core/signing-securosys"
},
"homepage": "https://github.com/canton-network/wallet/tree/main/core/signing-securosys#readme",
"bugs": {
"url": "https://github.com/canton-network/wallet/issues"
}
}
Loading
Loading