@distrohelena/canton-typescript-sdk 0.1.32 → 0.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -86,6 +86,12 @@ Participant 3.5.7. In particular, external-party allocation signs the generated
86
86
  combined topology hash (`multi_hash`) rather than each topology transaction
87
87
  individually.
88
88
 
89
+ The decentralized Ed25519 example was also run end-to-end against an isolated
90
+ Canton Participant 3.5.8 sidecar. On both 3.5.7 and 3.5.8 it creates the same
91
+ topology shape: a serial-1 decentralized namespace definition, one self-root
92
+ namespace certificate per owner, and a PartyToParticipant containing the party
93
+ signing key. No deprecated PartyToKeyMapping is created.
94
+
89
95
  ## Localnet launchers
90
96
 
91
97
  The published package includes launchers for an existing CN Quickstart checkout.
@@ -110,6 +116,56 @@ npm exec --package @distrohelena/canton-typescript-sdk canton-localnet-stop
110
116
  These commands launch and stop CN Quickstart; they do not provision a
111
117
  Quickstart checkout.
112
118
 
119
+ ### Optional Canton 3.5.8 participant sidecar
120
+
121
+ For SDK compatibility work, an isolated Canton 3.5.8 participant can join an
122
+ already-running CN Quickstart localnet without changing its files or Compose
123
+ project:
124
+
125
+ ```bash
126
+ canton-localnet-participant-358-start
127
+ canton-localnet-participant-358-stop
128
+ ```
129
+
130
+ The sidecar owns `.generated/participant-358`, its `canton-participant-358`
131
+ Compose project, its Postgres container, and host ports `8901` (Ledger), `8902`
132
+ (Admin), and `8975` (JSON). The start launcher reads the existing localnet's
133
+ registered synchronizer via its Admin API, stores the exported connection
134
+ configuration in the sidecar runtime directory, and connects the sidecar with
135
+ its own Admin API. It generates a five-minute 3.5.8-compatible development JWT
136
+ at `.generated/participant-358/ledger-api-user.token` and prints both live-test
137
+ and example endpoint/token exports when the connection is healthy.
138
+ `cn-quickstart` is strictly read-only: this launcher never writes to, starts,
139
+ or stops the normal Quickstart stack.
140
+
141
+ After copying the printed `SDK_EXAMPLE_*` exports into the current shell, run
142
+ the standalone decentralized-party comparison example with:
143
+
144
+ ```bash
145
+ npm run example:party:decentralized
146
+ ```
147
+
148
+ The defaults target the normal insecure shared-secret localnet at
149
+ `localhost:3902` on its `quickstart` Docker network. Override them when your
150
+ localnet differs:
151
+
152
+ ```bash
153
+ PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT=localhost:3902 \
154
+ PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN="$TOKEN" \
155
+ PARTICIPANT_358_NETWORK=quickstart \
156
+ canton-localnet-participant-358-start
157
+ ```
158
+
159
+ Use `PARTICIPANT_358_CANTON_IMAGE`, `PARTICIPANT_358_PROJECT_NAME`,
160
+ `PARTICIPANT_358_RUNTIME_DIR`, `PARTICIPANT_358_LEDGER_PORT`,
161
+ `PARTICIPANT_358_ADMIN_PORT`, and `PARTICIPANT_358_JSON_PORT` to make an
162
+ explicitly isolated variant. The opt-in Docker check requires a running
163
+ localnet and is never part of the normal test suite:
164
+
165
+ ```bash
166
+ PARTICIPANT_358_SMOKE_TEST=1 npm run test:participant-358-sidecar-smoke
167
+ ```
168
+
113
169
  ### Optional ES256 bearer tokens
114
170
 
115
171
  Set `LOCALNET_ES256_JWT=1` when starting the localnet to add ES256 JWT
@@ -15,6 +15,17 @@ async function prepareDecentralizedPartyAsync(request, localParticipant, topolog
15
15
  const partyId = `${request.partyHint}::${decentralizedNamespace}`;
16
16
  const owners = request.owners.map(toTopologyKey);
17
17
  const partyKeys = request.partySigningKeys.map(toTopologyKey);
18
+ const store = {
19
+ store: {
20
+ oneofKind: "synchronizer",
21
+ synchronizer: {
22
+ kind: {
23
+ oneofKind: "id",
24
+ id: request.synchronizer,
25
+ },
26
+ },
27
+ },
28
+ };
18
29
  const participants = [
19
30
  {
20
31
  participantUid: localParticipant.participantId,
@@ -30,6 +41,7 @@ async function prepareDecentralizedPartyAsync(request, localParticipant, topolog
30
41
  {
31
42
  operation: topology_js_1.Enums_TopologyChangeOp.ADD_REPLACE,
32
43
  serial: 1,
44
+ store,
33
45
  mapping: {
34
46
  mapping: {
35
47
  oneofKind: "decentralizedNamespaceDefinition",
@@ -41,14 +53,15 @@ async function prepareDecentralizedPartyAsync(request, localParticipant, topolog
41
53
  },
42
54
  },
43
55
  },
44
- ...owners.map((targetKey) => ({
56
+ ...owners.map((targetKey, index) => ({
45
57
  operation: topology_js_1.Enums_TopologyChangeOp.ADD_REPLACE,
46
58
  serial: 1,
59
+ store,
47
60
  mapping: {
48
61
  mapping: {
49
62
  oneofKind: "namespaceDelegation",
50
63
  namespaceDelegation: {
51
- namespace: decentralizedNamespace,
64
+ namespace: ownerFingerprints[index],
52
65
  targetKey,
53
66
  isRootDelegation: true,
54
67
  restriction: { oneofKind: undefined },
@@ -59,6 +72,7 @@ async function prepareDecentralizedPartyAsync(request, localParticipant, topolog
59
72
  {
60
73
  operation: topology_js_1.Enums_TopologyChangeOp.ADD_REPLACE,
61
74
  serial: 1,
75
+ store,
62
76
  mapping: {
63
77
  mapping: {
64
78
  oneofKind: "partyToParticipant",
@@ -12,6 +12,17 @@ export async function prepareDecentralizedPartyAsync(request, localParticipant,
12
12
  const partyId = `${request.partyHint}::${decentralizedNamespace}`;
13
13
  const owners = request.owners.map(toTopologyKey);
14
14
  const partyKeys = request.partySigningKeys.map(toTopologyKey);
15
+ const store = {
16
+ store: {
17
+ oneofKind: "synchronizer",
18
+ synchronizer: {
19
+ kind: {
20
+ oneofKind: "id",
21
+ id: request.synchronizer,
22
+ },
23
+ },
24
+ },
25
+ };
15
26
  const participants = [
16
27
  {
17
28
  participantUid: localParticipant.participantId,
@@ -27,6 +38,7 @@ export async function prepareDecentralizedPartyAsync(request, localParticipant,
27
38
  {
28
39
  operation: Enums_TopologyChangeOp.ADD_REPLACE,
29
40
  serial: 1,
41
+ store,
30
42
  mapping: {
31
43
  mapping: {
32
44
  oneofKind: "decentralizedNamespaceDefinition",
@@ -38,14 +50,15 @@ export async function prepareDecentralizedPartyAsync(request, localParticipant,
38
50
  },
39
51
  },
40
52
  },
41
- ...owners.map((targetKey) => ({
53
+ ...owners.map((targetKey, index) => ({
42
54
  operation: Enums_TopologyChangeOp.ADD_REPLACE,
43
55
  serial: 1,
56
+ store,
44
57
  mapping: {
45
58
  mapping: {
46
59
  oneofKind: "namespaceDelegation",
47
60
  namespaceDelegation: {
48
- namespace: decentralizedNamespace,
61
+ namespace: ownerFingerprints[index],
49
62
  targetKey,
50
63
  isRootDelegation: true,
51
64
  restriction: { oneofKind: undefined },
@@ -56,6 +69,7 @@ export async function prepareDecentralizedPartyAsync(request, localParticipant,
56
69
  {
57
70
  operation: Enums_TopologyChangeOp.ADD_REPLACE,
58
71
  serial: 1,
72
+ store,
59
73
  mapping: {
60
74
  mapping: {
61
75
  oneofKind: "partyToParticipant",
@@ -0,0 +1,142 @@
1
+ import { createHmac } from "node:crypto";
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { credentials } from "@grpc/grpc-js";
4
+ import { GrpcTransport } from "@protobuf-ts/grpc-transport";
5
+ import { SynchronizerConnectivityServiceClient } from "../dist/transports/grpc/generated/canton/com/digitalasset/canton/admin/participant/v30/synchronizer_connectivity_service.client.js";
6
+ import { ListRegisteredSynchronizersResponse_Status } from "../dist/transports/grpc/generated/canton/com/digitalasset/canton/admin/participant/v30/synchronizer_connectivity_service.js";
7
+ import { SequencerConnectionValidation } from "../dist/transports/grpc/generated/canton/com/digitalasset/canton/admin/sequencer/v30/sequencer_connection.js";
8
+ import { VersionServiceClient } from "../dist/transports/grpc/generated/canton/com/daml/ledger/api/v2/version_service.client.js";
9
+
10
+ function getRequiredEnvironment(name) {
11
+ const value = process.env[name];
12
+ if (!value) throw new Error(`${name} must be set.`);
13
+ return value;
14
+ }
15
+
16
+ function createSharedSecretToken() {
17
+ const secret = process.env.PARTICIPANT_358_SOURCE_SHARED_SECRET ?? "unsafe";
18
+ const audience = process.env.PARTICIPANT_358_SOURCE_AUTH_AUDIENCE
19
+ ?? "https://canton.network.global";
20
+ const subject = process.env.PARTICIPANT_358_SOURCE_AUTH_SUBJECT
21
+ ?? "ledger-api-user";
22
+ const ttlSeconds = Number.parseInt(
23
+ process.env.PARTICIPANT_358_TOKEN_TTL_SECONDS ?? "300",
24
+ 10,
25
+ );
26
+ if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0) {
27
+ throw new Error("PARTICIPANT_358_TOKEN_TTL_SECONDS must be a positive integer.");
28
+ }
29
+ const issuedAt = Math.floor(Date.now() / 1000);
30
+ const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
31
+ const payload = Buffer.from(JSON.stringify({
32
+ aud: audience,
33
+ sub: subject,
34
+ iat: issuedAt,
35
+ exp: issuedAt + ttlSeconds,
36
+ })).toString("base64url");
37
+ const signature = createHmac("sha256", secret)
38
+ .update(`${header}.${payload}`)
39
+ .digest("base64url");
40
+ return `${header}.${payload}.${signature}`;
41
+ }
42
+
43
+ async function writeLedgerToken() {
44
+ const targetFile = getRequiredEnvironment("PARTICIPANT_358_LEDGER_TOKEN_FILE");
45
+ await writeFile(targetFile, `${createSharedSecretToken()}\n`, { mode: 0o600 });
46
+ }
47
+
48
+ function createClient(endpoint, token) {
49
+ const transport = new GrpcTransport({
50
+ host: endpoint.replace(/^https?:\/\//, ""),
51
+ channelCredentials: credentials.createInsecure(),
52
+ });
53
+ const options = token ? { meta: { authorization: `Bearer ${token}` } } : undefined;
54
+ return { client: new SynchronizerConnectivityServiceClient(transport), options, transport };
55
+ }
56
+
57
+ function encode(value) {
58
+ if (value instanceof Uint8Array) return { $bytes: Buffer.from(value).toString("base64") };
59
+ if (Array.isArray(value)) return value.map(encode);
60
+ if (value && typeof value === "object") {
61
+ return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, encode(nested)]));
62
+ }
63
+ return value;
64
+ }
65
+
66
+ function decode(value) {
67
+ if (Array.isArray(value)) return value.map(decode);
68
+ if (value && typeof value === "object") {
69
+ if (typeof value.$bytes === "string") return Buffer.from(value.$bytes, "base64");
70
+ return Object.fromEntries(Object.entries(value).map(([key, nested]) => [key, decode(nested)]));
71
+ }
72
+ return value;
73
+ }
74
+
75
+ async function exportSynchronizerConfig() {
76
+ const targetFile = getRequiredEnvironment("PARTICIPANT_358_SYNCHRONIZER_CONFIG");
77
+ const sourceEndpoint = getRequiredEnvironment("PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT");
78
+ const sourceToken = process.env.PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN ?? createSharedSecretToken();
79
+ const { client, options, transport } = createClient(sourceEndpoint, sourceToken);
80
+ try {
81
+ const response = await client.listRegisteredSynchronizers({ allStatuses: false }, options).response;
82
+ const connected = response.results.filter((result) => result.connected && result.config);
83
+ if (connected.length !== 1) {
84
+ throw new Error(`Expected exactly one connected synchronizer from ${sourceEndpoint}; found ${connected.length}. Set PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT to a participant with one connected synchronizer.`);
85
+ }
86
+ await writeFile(targetFile, `${JSON.stringify(encode(connected[0].config), null, 2)}\n`, { mode: 0o600 });
87
+ } finally {
88
+ transport.close();
89
+ }
90
+ }
91
+
92
+ async function connectSynchronizer() {
93
+ const configFile = getRequiredEnvironment("PARTICIPANT_358_SYNCHRONIZER_CONFIG");
94
+ const targetEndpoint = getRequiredEnvironment("PARTICIPANT_358_ADMIN_ENDPOINT");
95
+ const targetToken = process.env.PARTICIPANT_358_ADMIN_BEARER_TOKEN ?? createSharedSecretToken();
96
+ const config = decode(JSON.parse(await readFile(configFile, "utf8")));
97
+ const { client, options, transport } = createClient(targetEndpoint, targetToken);
98
+ try {
99
+ const connectResponse = await client.connectSynchronizer({
100
+ config,
101
+ sequencerConnectionValidation: SequencerConnectionValidation.ALL,
102
+ }, options).response;
103
+ if (!connectResponse.connectedSuccessfully) {
104
+ throw new Error("ConnectSynchronizer completed without a healthy connection.");
105
+ }
106
+ const registered = await client.listRegisteredSynchronizers({ allStatuses: false }, options).response;
107
+ const isHealthy = registered.results.some(
108
+ (result) => result.connected
109
+ && result.status === ListRegisteredSynchronizersResponse_Status.ACTIVE
110
+ && result.config?.synchronizerAlias === config.synchronizerAlias,
111
+ );
112
+ if (!isHealthy) throw new Error("Synchronizer did not reach active/connected state.");
113
+ } finally {
114
+ transport.close();
115
+ }
116
+ }
117
+
118
+ async function readLedgerApiVersion() {
119
+ const endpoint = getRequiredEnvironment("PARTICIPANT_358_LEDGER_ENDPOINT");
120
+ const token = process.env.PARTICIPANT_358_LEDGER_BEARER_TOKEN ?? createSharedSecretToken();
121
+ const { options, transport } = createClient(endpoint, token);
122
+ try {
123
+ const response = await new VersionServiceClient(transport)
124
+ .getLedgerApiVersion({}, options).response;
125
+ process.stdout.write(`${response.version}\n`);
126
+ } finally {
127
+ transport.close();
128
+ }
129
+ }
130
+
131
+ const command = process.argv[2];
132
+ if (command === "export") {
133
+ await exportSynchronizerConfig();
134
+ } else if (command === "connect") {
135
+ await connectSynchronizer();
136
+ } else if (command === "ledger-api-version") {
137
+ await readLedgerApiVersion();
138
+ } else if (command === "mint-ledger-token") {
139
+ await writeLedgerToken();
140
+ } else {
141
+ throw new Error("Expected 'export', 'connect', 'ledger-api-version', or 'mint-ledger-token'.");
142
+ }
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
5
+ REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
6
+ RUNTIME_DIR="${PARTICIPANT_358_RUNTIME_DIR:-$REPO_ROOT/.generated/participant-358}"
7
+ PROJECT_NAME="${PARTICIPANT_358_PROJECT_NAME:-canton-participant-358}"
8
+ CANTON_IMAGE="${PARTICIPANT_358_CANTON_IMAGE:-ghcr.io/digital-asset/decentralized-canton-sync/docker/canton:0.6.12}"
9
+ POSTGRES_IMAGE="${PARTICIPANT_358_POSTGRES_IMAGE:-postgres:16}"
10
+ NETWORK_NAME="${PARTICIPANT_358_NETWORK:-quickstart}"
11
+ LEDGER_PORT="${PARTICIPANT_358_LEDGER_PORT:-8901}"
12
+ ADMIN_PORT="${PARTICIPANT_358_ADMIN_PORT:-8902}"
13
+ JSON_PORT="${PARTICIPANT_358_JSON_PORT:-8975}"
14
+ SOURCE_ADMIN_ENDPOINT="${PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT:-localhost:3902}"
15
+ DOCKER_COMPOSE_CMD=()
16
+
17
+ resolve_docker_compose_cmd() {
18
+ if docker compose version >/dev/null 2>&1; then DOCKER_COMPOSE_CMD=(docker compose); return; fi
19
+ if docker-compose version >/dev/null 2>&1; then DOCKER_COMPOSE_CMD=(docker-compose); return; fi
20
+ echo "Unable to find a working Docker Compose command." >&2
21
+ exit 1
22
+ }
23
+
24
+ validate_port() {
25
+ local value="$1"
26
+ [[ "$value" =~ ^[1-9][0-9]{0,4}$ ]] && (( value <= 65535 )) || { echo "Invalid port: $value" >&2; exit 1; }
27
+ }
28
+
29
+ for port in "$LEDGER_PORT" "$ADMIN_PORT" "$JSON_PORT"; do validate_port "$port"; done
30
+ if [[ "$LEDGER_PORT" == "$ADMIN_PORT" || "$LEDGER_PORT" == "$JSON_PORT" || "$ADMIN_PORT" == "$JSON_PORT" ]]; then
31
+ echo "Participant 3.5.8 Ledger, Admin, and JSON ports must be distinct." >&2
32
+ exit 1
33
+ fi
34
+ for normal_port in 3901 3902 3975; do
35
+ if [[ "$LEDGER_PORT" == "$normal_port" || "$ADMIN_PORT" == "$normal_port" || "$JSON_PORT" == "$normal_port" ]]; then
36
+ echo "Participant 3.5.8 ports must not collide with CN Quickstart ports." >&2
37
+ exit 1
38
+ fi
39
+ done
40
+
41
+ assert_host_port_available() {
42
+ local port="$1"
43
+ if command -v ss >/dev/null 2>&1 && ss -ltn "sport = :$port" | tail -n +2 | grep -q .; then
44
+ echo "Host port $port is already in use. Set the corresponding PARTICIPANT_358_*_PORT value." >&2
45
+ exit 1
46
+ fi
47
+ }
48
+ for port in "$LEDGER_PORT" "$ADMIN_PORT" "$JSON_PORT"; do assert_host_port_available "$port"; done
49
+
50
+ mkdir -p "$RUNTIME_DIR"
51
+ chmod 700 "$RUNTIME_DIR"
52
+ SYNCHRONIZER_CONFIG="$RUNTIME_DIR/registered-synchronizer.json"
53
+ LEDGER_TOKEN_FILE="$RUNTIME_DIR/ledger-api-user.token"
54
+ PARTICIPANT_358_LEDGER_TOKEN_FILE="$LEDGER_TOKEN_FILE" \
55
+ node "$SCRIPT_DIR/participant-358-synchronizer.mjs" mint-ledger-token
56
+ cat > "$RUNTIME_DIR/participant-358.env" <<EOF
57
+ PARTICIPANT_358_SYNCHRONIZER_CONFIG=$SYNCHRONIZER_CONFIG
58
+ PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT=$SOURCE_ADMIN_ENDPOINT
59
+ PARTICIPANT_358_ADMIN_ENDPOINT=localhost:$ADMIN_PORT
60
+ PARTICIPANT_358_LEDGER_TOKEN_FILE=$LEDGER_TOKEN_FILE
61
+ EOF
62
+ chmod 600 "$RUNTIME_DIR/participant-358.env"
63
+
64
+ cat > "$RUNTIME_DIR/canton.conf" <<EOF
65
+ canton {
66
+ parameters { manual-start = no }
67
+ participants.participant358 {
68
+ storage {
69
+ type = postgres
70
+ config {
71
+ dataSourceClass = "org.postgresql.ds.PGSimpleDataSource"
72
+ properties {
73
+ serverName = \${?DB_SERVER}
74
+ portNumber = 5432
75
+ databaseName = participant358
76
+ currentSchema = participant358
77
+ user = \${?DB_USER}
78
+ password = \${?DB_PASSWORD}
79
+ }
80
+ }
81
+ }
82
+ init {
83
+ generate-topology-transactions-and-keys = true
84
+ identity.type = auto
85
+ }
86
+ admin-api {
87
+ address = "0.0.0.0"
88
+ port = 5002
89
+ }
90
+ ledger-api {
91
+ address = "0.0.0.0"
92
+ port = 5001
93
+ auth-services = [{
94
+ type = unsafe-jwt-hmac-256
95
+ target-audience = "https://canton.network.global"
96
+ secret = "unsafe"
97
+ }]
98
+ user-management-service.additional-admin-user-id = "ledger-api-user"
99
+ }
100
+ http-ledger-api {
101
+ address = "0.0.0.0"
102
+ port = 7575
103
+ }
104
+ monitoring.http-health-server {
105
+ address = "0.0.0.0"
106
+ port = 7000
107
+ }
108
+ }
109
+ }
110
+ EOF
111
+
112
+ cat > "$RUNTIME_DIR/compose.yaml" <<EOF
113
+ name: $PROJECT_NAME
114
+ services:
115
+ postgres:
116
+ image: $POSTGRES_IMAGE
117
+ environment:
118
+ POSTGRES_DB: participant358
119
+ POSTGRES_USER: participant358
120
+ POSTGRES_PASSWORD: participant358
121
+ healthcheck:
122
+ test: ["CMD-SHELL", "pg_isready -U participant358 -d participant358"]
123
+ interval: 2s
124
+ timeout: 3s
125
+ retries: 30
126
+ participant358:
127
+ image: $CANTON_IMAGE
128
+ depends_on:
129
+ postgres:
130
+ condition: service_healthy
131
+ environment:
132
+ DB_SERVER: postgres
133
+ DB_USER: participant358
134
+ DB_PASSWORD: participant358
135
+ volumes:
136
+ - "$RUNTIME_DIR/canton.conf:/app/app.conf:ro"
137
+ ports:
138
+ - "127.0.0.1:$LEDGER_PORT:5001"
139
+ - "127.0.0.1:$ADMIN_PORT:5002"
140
+ - "127.0.0.1:$JSON_PORT:7575"
141
+ networks:
142
+ - default
143
+ - localnet
144
+ networks:
145
+ localnet:
146
+ external: true
147
+ name: $NETWORK_NAME
148
+ EOF
149
+
150
+ if [[ "${PARTICIPANT_358_SKIP_SYNCHRONIZER_CONNECT:-0}" != "1" ]]; then
151
+ PARTICIPANT_358_SYNCHRONIZER_CONFIG="$SYNCHRONIZER_CONFIG" \
152
+ PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT="$SOURCE_ADMIN_ENDPOINT" \
153
+ PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN="${PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN:-}" \
154
+ node "$SCRIPT_DIR/participant-358-synchronizer.mjs" export
155
+ fi
156
+
157
+ resolve_docker_compose_cmd
158
+ "${DOCKER_COMPOSE_CMD[@]}" --project-name "$PROJECT_NAME" --file "$RUNTIME_DIR/compose.yaml" up -d
159
+
160
+ if [[ "${PARTICIPANT_358_SKIP_SYNCHRONIZER_CONNECT:-0}" != "1" ]]; then
161
+ deadline=$((SECONDS + ${PARTICIPANT_358_CONNECT_TIMEOUT_SECONDS:-90}))
162
+ until PARTICIPANT_358_SYNCHRONIZER_CONFIG="$SYNCHRONIZER_CONFIG" \
163
+ PARTICIPANT_358_ADMIN_ENDPOINT="localhost:$ADMIN_PORT" \
164
+ PARTICIPANT_358_ADMIN_BEARER_TOKEN="${PARTICIPANT_358_ADMIN_BEARER_TOKEN:-}" \
165
+ node "$SCRIPT_DIR/participant-358-synchronizer.mjs" connect
166
+ do
167
+ if (( SECONDS >= deadline )); then
168
+ echo "Participant 3.5.8 sidecar did not become ready. Inspect: ${DOCKER_COMPOSE_CMD[*]} --project-name $PROJECT_NAME --file $RUNTIME_DIR/compose.yaml logs participant358" >&2
169
+ exit 1
170
+ fi
171
+ sleep 2
172
+ done
173
+ fi
174
+
175
+ cat <<EOF
176
+ Participant 3.5.8 sidecar is ready.
177
+ export SDK_TEST_LEDGER_ENDPOINT=localhost:$LEDGER_PORT
178
+ export SDK_TEST_LEDGER_ADMIN_ENDPOINT=localhost:$LEDGER_PORT
179
+ export SDK_TEST_PARTICIPANT_ADMIN_ENDPOINT=localhost:$ADMIN_PORT
180
+ export SDK_EXAMPLE_LEDGER_ENDPOINT=localhost:$LEDGER_PORT
181
+ export SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT=localhost:$LEDGER_PORT
182
+ export SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT=localhost:$ADMIN_PORT
183
+ export SDK_EXAMPLE_BEARER_TOKEN="\$(cat $LEDGER_TOKEN_FILE)"
184
+ EOF
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
5
+ REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
6
+ RUNTIME_DIR="${PARTICIPANT_358_RUNTIME_DIR:-$REPO_ROOT/.generated/participant-358}"
7
+ PROJECT_NAME="${PARTICIPANT_358_PROJECT_NAME:-canton-participant-358}"
8
+ DOCKER_COMPOSE_CMD=()
9
+
10
+ if [[ ! -f "$RUNTIME_DIR/compose.yaml" ]]; then
11
+ echo "Participant 3.5.8 sidecar is not configured. Nothing to stop."
12
+ exit 0
13
+ fi
14
+ if docker compose version >/dev/null 2>&1; then DOCKER_COMPOSE_CMD=(docker compose); elif docker-compose version >/dev/null 2>&1; then DOCKER_COMPOSE_CMD=(docker-compose); else
15
+ echo "Unable to find a working Docker Compose command." >&2
16
+ exit 1
17
+ fi
18
+ "${DOCKER_COMPOSE_CMD[@]}" --project-name "$PROJECT_NAME" --file "$RUNTIME_DIR/compose.yaml" down --volumes --remove-orphans
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ if [[ "${PARTICIPANT_358_SMOKE_TEST:-0}" != "1" ]]; then
5
+ echo "Set PARTICIPANT_358_SMOKE_TEST=1 to run this Docker smoke test against an already-running CN Quickstart localnet."
6
+ exit 0
7
+ fi
8
+
9
+ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
10
+ REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
11
+ trap 'bash "$SCRIPT_DIR/stop-local-participant-358.sh"' EXIT
12
+
13
+ bash "$SCRIPT_DIR/start-local-participant-358.sh"
14
+ version="$(PARTICIPANT_358_LEDGER_ENDPOINT="localhost:${PARTICIPANT_358_LEDGER_PORT:-8901}" node "$SCRIPT_DIR/participant-358-synchronizer.mjs" ledger-api-version)"
15
+ [[ "$version" == 3.5.8* ]] || {
16
+ echo "Expected Canton 3.5.8 Ledger API response, received: $version" >&2
17
+ exit 1
18
+ }
19
+ echo "Participant 3.5.8 Ledger API response: $version"
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ START_SCRIPT="$REPO_ROOT/node/start-local-participant-358.sh"
6
+ STOP_SCRIPT="$REPO_ROOT/node/stop-local-participant-358.sh"
7
+
8
+ [[ -x "$START_SCRIPT" ]]
9
+ [[ -x "$STOP_SCRIPT" ]]
10
+ grep -Fq 'export SDK_EXAMPLE_LEDGER_ENDPOINT=localhost:$LEDGER_PORT' "$START_SCRIPT"
11
+ grep -Fq 'export SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT=localhost:$LEDGER_PORT' "$START_SCRIPT"
12
+ grep -Fq 'export SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT=localhost:$ADMIN_PORT' "$START_SCRIPT"
13
+
14
+ tmpdir="$(mktemp -d)"
15
+ trap 'rm -rf "$tmpdir"' EXIT
16
+
17
+ stubbin="$tmpdir/bin"
18
+ mkdir -p "$stubbin"
19
+ cat > "$stubbin/docker" <<'EOF'
20
+ #!/usr/bin/env bash
21
+ set -euo pipefail
22
+ printf '%s\n' "$*" >> "$DOCKER_LOG"
23
+ if [[ "$1" == "compose" && "$2" == "version" ]]; then
24
+ exit 0
25
+ fi
26
+ EOF
27
+ chmod +x "$stubbin/docker"
28
+
29
+ runtime_dir="$tmpdir/runtime"
30
+ docker_log="$tmpdir/docker.log"
31
+ PATH="$stubbin:$PATH" \
32
+ DOCKER_LOG="$docker_log" \
33
+ PARTICIPANT_358_RUNTIME_DIR="$runtime_dir" \
34
+ PARTICIPANT_358_SKIP_SYNCHRONIZER_CONNECT=1 \
35
+ "$START_SCRIPT"
36
+
37
+ grep -Fqx 'name: canton-participant-358' "$runtime_dir/compose.yaml"
38
+ grep -Fqx ' participant358:' "$runtime_dir/compose.yaml"
39
+ if grep -Fqx ' canton:' "$runtime_dir/compose.yaml"; then
40
+ echo 'sidecar must not claim the quickstart canton DNS alias' >&2
41
+ exit 1
42
+ fi
43
+ grep -Fqx ' image: ghcr.io/digital-asset/decentralized-canton-sync/docker/canton:0.6.12' "$runtime_dir/compose.yaml"
44
+ grep -Fqx ' image: postgres:16' "$runtime_dir/compose.yaml"
45
+ grep -Fqx ' - default' "$runtime_dir/compose.yaml"
46
+ grep -Fqx ' - localnet' "$runtime_dir/compose.yaml"
47
+ grep -Fqx ' databaseName = participant358' "$runtime_dir/canton.conf"
48
+ grep -Fqx ' admin-api {' "$runtime_dir/canton.conf"
49
+ grep -Fqx ' address = "0.0.0.0"' "$runtime_dir/canton.conf"
50
+ grep -Fqx ' port = 5002' "$runtime_dir/canton.conf"
51
+ grep -Fqx ' - "127.0.0.1:8901:5001"' "$runtime_dir/compose.yaml"
52
+ grep -Fqx ' port = 5002' "$runtime_dir/canton.conf"
53
+ grep -Fqx ' port = 7575' "$runtime_dir/canton.conf"
54
+ grep -Fq 'PARTICIPANT_358_SYNCHRONIZER_CONFIG=' "$runtime_dir/participant-358.env"
55
+ grep -Fq 'PARTICIPANT_358_LEDGER_TOKEN_FILE=' "$runtime_dir/participant-358.env"
56
+ test -s "$runtime_dir/ledger-api-user.token"
57
+ node -e '
58
+ const token = require("node:fs").readFileSync(process.argv[1], "utf8").trim();
59
+ const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));
60
+ if (payload.sub !== "ledger-api-user") throw new Error("unexpected token subject");
61
+ if (payload.aud !== "https://canton.network.global") throw new Error("unexpected token audience");
62
+ if (!Number.isInteger(payload.iat)) throw new Error("token is missing iat");
63
+ if (!Number.isInteger(payload.exp) || payload.exp <= payload.iat) throw new Error("token is missing a future exp");
64
+ if (payload.exp - payload.iat !== 300) throw new Error("token lifetime must be 300 seconds");
65
+ ' "$runtime_dir/ledger-api-user.token"
66
+ grep -F -- '--project-name canton-participant-358' "$docker_log"
67
+ grep -Fqx ' name: quickstart' "$runtime_dir/compose.yaml"
68
+
69
+ if PATH="$stubbin:$PATH" PARTICIPANT_358_LEDGER_PORT=3901 "$START_SCRIPT" >/dev/null 2>&1; then
70
+ echo 'sidecar launcher accepted a CN Quickstart Ledger port' >&2
71
+ exit 1
72
+ fi
73
+
74
+ PATH="$stubbin:$PATH" \
75
+ DOCKER_LOG="$docker_log" \
76
+ PARTICIPANT_358_RUNTIME_DIR="$runtime_dir" \
77
+ "$STOP_SCRIPT"
78
+
79
+ grep -F -- '--project-name canton-participant-358' "$docker_log"
80
+ if grep -Eq -- '(^| )down( |$).*quickstart|quickstart.*(^| )down( |$)' "$docker_log"; then
81
+ echo 'stop launcher targeted quickstart' >&2
82
+ exit 1
83
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distrohelena/canton-typescript-sdk",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,7 +13,9 @@
13
13
  ],
14
14
  "bin": {
15
15
  "canton-localnet-start": "node/start-local.sh",
16
- "canton-localnet-stop": "node/stop-local.sh"
16
+ "canton-localnet-stop": "node/stop-local.sh",
17
+ "canton-localnet-participant-358-start": "node/start-local-participant-358.sh",
18
+ "canton-localnet-participant-358-stop": "node/stop-local-participant-358.sh"
17
19
  },
18
20
  "keywords": [
19
21
  "canton",
@@ -90,8 +92,12 @@
90
92
  "lint:fix": "eslint . --fix --max-warnings=0",
91
93
  "start:local-ledger": "bash node/start-local.sh",
92
94
  "stop:local-ledger": "bash node/stop-local.sh",
95
+ "start:local-participant-358": "bash node/start-local-participant-358.sh",
96
+ "stop:local-participant-358": "bash node/stop-local-participant-358.sh",
93
97
  "test:start-local-script": "bash node/test-start-local.sh",
94
98
  "test:stop-local-script": "bash node/test-stop-local.sh",
99
+ "test:participant-358-sidecar-script": "bash node/test-participant-358-sidecar.sh",
100
+ "test:participant-358-sidecar-smoke": "bash node/test-participant-358-sidecar-smoke.sh",
95
101
  "test": "vitest run --maxWorkers=1 --testTimeout=15000",
96
102
  "test:property": "vitest run tests/property --maxWorkers=1 --testTimeout=15000",
97
103
  "test:live": "vitest run tests/live --maxWorkers=1 --testTimeout=15000",
@@ -1,72 +0,0 @@
1
- canton.participants.extra-1 = $${_participant} {
2
- storage.config.properties.databaseName = "participant-extra-1"
3
- init {
4
- generate-topology-transactions-and-keys = true
5
- identity.type = auto
6
- }
7
- monitoring {
8
- http-health-server.port = ${EXTRA_PARTICIPANT_1_HTTP_HEALTHCHECK_PORT}
9
- grpc-health-server.port = ${EXTRA_PARTICIPANT_1_GRPC_HEALTHCHECK_PORT}
10
- }
11
- http-ledger-api.port = ${EXTRA_PARTICIPANT_1_JSON_API_PORT}
12
- admin-api.port = ${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}
13
- ledger-api.port = ${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}
14
- ledger-api {
15
- auth-services = [{
16
- type = unsafe-jwt-hmac-256
17
- target-audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
18
- secret = "unsafe"
19
- }]
20
-
21
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_1_USER_NAME}"
22
- }
23
- }
24
-
25
- canton.participants.extra-2 = $${_participant} {
26
- storage.config.properties.databaseName = "participant-extra-2"
27
- init {
28
- generate-topology-transactions-and-keys = true
29
- identity.type = auto
30
- }
31
- monitoring {
32
- http-health-server.port = ${EXTRA_PARTICIPANT_2_HTTP_HEALTHCHECK_PORT}
33
- grpc-health-server.port = ${EXTRA_PARTICIPANT_2_GRPC_HEALTHCHECK_PORT}
34
- }
35
- http-ledger-api.port = ${EXTRA_PARTICIPANT_2_JSON_API_PORT}
36
- admin-api.port = ${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}
37
- ledger-api.port = ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
38
- ledger-api {
39
- auth-services = [{
40
- type = unsafe-jwt-hmac-256
41
- target-audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
42
- secret = "unsafe"
43
- }]
44
-
45
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_2_USER_NAME}"
46
- }
47
- }
48
-
49
- canton.participants.extra-3 = $${_participant} {
50
- storage.config.properties.databaseName = "participant-extra-3"
51
- init {
52
- generate-topology-transactions-and-keys = true
53
- identity.type = auto
54
- }
55
- monitoring {
56
- http-health-server.port = ${EXTRA_PARTICIPANT_3_HTTP_HEALTHCHECK_PORT}
57
- grpc-health-server.port = ${EXTRA_PARTICIPANT_3_GRPC_HEALTHCHECK_PORT}
58
- }
59
- http-ledger-api.port = ${EXTRA_PARTICIPANT_3_JSON_API_PORT}
60
- admin-api.port = ${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}
61
- ledger-api.port = ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
62
- ledger-api {
63
- auth-services = [{
64
- type = unsafe-jwt-hmac-256
65
- target-audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
66
- secret = "unsafe"
67
- }]
68
-
69
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_3_USER_NAME}"
70
- }
71
- }
72
-
@@ -1,105 +0,0 @@
1
- canton.validator-apps.extra-1-validator_backend = $${_validator_backend} {
2
- onboarding.secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}"
3
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-1.json"
4
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_1_DB}"
5
- admin-api.port = ${EXTRA_VALIDATOR_1_ADMIN_API_PORT}
6
- canton-identifier-config.participant = extra-1
7
- participant-client {
8
- admin-api.port = ${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}
9
- ledger-api {
10
- client-config.port = ${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}
11
- auth-config = {
12
- type = "self-signed"
13
- user = "${EXTRA_VALIDATOR_1_USER_NAME}"
14
- audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
15
- secret = "unsafe"
16
- }
17
- }
18
- }
19
- auth = {
20
- algorithm = "hs-256-unsafe"
21
- audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
22
- secret = "unsafe"
23
- }
24
- ledger-api-user = "${EXTRA_VALIDATOR_1_USER_NAME}"
25
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_1_WALLET_ADMIN_USER_NAME}"
26
- validator-party-hint = "${EXTRA_VALIDATOR_1_PARTY_HINT}"
27
-
28
- domains.global.buy-extra-traffic {
29
- min-topup-interval = ${?MIN_TRAFFIC_TOPUP_INTERVAL}
30
- target-throughput = ${?TARGET_TRAFFIC_THROUGHPUT}
31
- }
32
- }
33
-
34
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}" }
35
-
36
- canton.validator-apps.extra-2-validator_backend = $${_validator_backend} {
37
- onboarding.secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}"
38
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-2.json"
39
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_2_DB}"
40
- admin-api.port = ${EXTRA_VALIDATOR_2_ADMIN_API_PORT}
41
- canton-identifier-config.participant = extra-2
42
- participant-client {
43
- admin-api.port = ${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}
44
- ledger-api {
45
- client-config.port = ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
46
- auth-config = {
47
- type = "self-signed"
48
- user = "${EXTRA_VALIDATOR_2_USER_NAME}"
49
- audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
50
- secret = "unsafe"
51
- }
52
- }
53
- }
54
- auth = {
55
- algorithm = "hs-256-unsafe"
56
- audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
57
- secret = "unsafe"
58
- }
59
- ledger-api-user = "${EXTRA_VALIDATOR_2_USER_NAME}"
60
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_2_WALLET_ADMIN_USER_NAME}"
61
- validator-party-hint = "${EXTRA_VALIDATOR_2_PARTY_HINT}"
62
-
63
- domains.global.buy-extra-traffic {
64
- min-topup-interval = ${?MIN_TRAFFIC_TOPUP_INTERVAL}
65
- target-throughput = ${?TARGET_TRAFFIC_THROUGHPUT}
66
- }
67
- }
68
-
69
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}" }
70
-
71
- canton.validator-apps.extra-3-validator_backend = $${_validator_backend} {
72
- onboarding.secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}"
73
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-3.json"
74
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_3_DB}"
75
- admin-api.port = ${EXTRA_VALIDATOR_3_ADMIN_API_PORT}
76
- canton-identifier-config.participant = extra-3
77
- participant-client {
78
- admin-api.port = ${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}
79
- ledger-api {
80
- client-config.port = ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
81
- auth-config = {
82
- type = "self-signed"
83
- user = "${EXTRA_VALIDATOR_3_USER_NAME}"
84
- audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
85
- secret = "unsafe"
86
- }
87
- }
88
- }
89
- auth = {
90
- algorithm = "hs-256-unsafe"
91
- audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
92
- secret = "unsafe"
93
- }
94
- ledger-api-user = "${EXTRA_VALIDATOR_3_USER_NAME}"
95
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_3_WALLET_ADMIN_USER_NAME}"
96
- validator-party-hint = "${EXTRA_VALIDATOR_3_PARTY_HINT}"
97
-
98
- domains.global.buy-extra-traffic {
99
- min-topup-interval = ${?MIN_TRAFFIC_TOPUP_INTERVAL}
100
- target-throughput = ${?TARGET_TRAFFIC_THROUGHPUT}
101
- }
102
- }
103
-
104
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}" }
105
-
@@ -1,366 +0,0 @@
1
- volumes:
2
- postgres-pqs-extra-1:
3
- postgres-pqs-extra-2:
4
- postgres-pqs-extra-3:
5
-
6
- services:
7
- postgres:
8
- env_file:
9
- - ${START_LOCAL_GENERATED_DIR}/extra-participants.env
10
- canton:
11
- env_file:
12
- - ${START_LOCAL_GENERATED_DIR}/extra-participants.env
13
- environment:
14
- ADDITIONAL_CONFIG_EXTRA_PARTICIPANTS: |
15
- canton.participants.extra-1 = $${_participant} {
16
- storage.config.properties.databaseName = "participant-extra-1"
17
- init {
18
- generate-topology-transactions-and-keys = true
19
- identity.type = auto
20
- }
21
- monitoring {
22
- http-health-server.port = ${EXTRA_PARTICIPANT_1_HTTP_HEALTHCHECK_PORT}
23
- grpc-health-server.port = ${EXTRA_PARTICIPANT_1_GRPC_HEALTHCHECK_PORT}
24
- }
25
- http-ledger-api.port = ${EXTRA_PARTICIPANT_1_JSON_API_PORT}
26
- admin-api.port = ${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}
27
- ledger-api.port = ${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}
28
- ledger-api {
29
- auth-services = [{
30
- type = unsafe-jwt-hmac-256
31
- target-audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
32
- secret = "unsafe"
33
- }]
34
-
35
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_1_USER_NAME}"
36
- }
37
- }
38
-
39
- canton.participants.extra-2 = $${_participant} {
40
- storage.config.properties.databaseName = "participant-extra-2"
41
- init {
42
- generate-topology-transactions-and-keys = true
43
- identity.type = auto
44
- }
45
- monitoring {
46
- http-health-server.port = ${EXTRA_PARTICIPANT_2_HTTP_HEALTHCHECK_PORT}
47
- grpc-health-server.port = ${EXTRA_PARTICIPANT_2_GRPC_HEALTHCHECK_PORT}
48
- }
49
- http-ledger-api.port = ${EXTRA_PARTICIPANT_2_JSON_API_PORT}
50
- admin-api.port = ${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}
51
- ledger-api.port = ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
52
- ledger-api {
53
- auth-services = [{
54
- type = unsafe-jwt-hmac-256
55
- target-audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
56
- secret = "unsafe"
57
- }]
58
-
59
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_2_USER_NAME}"
60
- }
61
- }
62
-
63
- canton.participants.extra-3 = $${_participant} {
64
- storage.config.properties.databaseName = "participant-extra-3"
65
- init {
66
- generate-topology-transactions-and-keys = true
67
- identity.type = auto
68
- }
69
- monitoring {
70
- http-health-server.port = ${EXTRA_PARTICIPANT_3_HTTP_HEALTHCHECK_PORT}
71
- grpc-health-server.port = ${EXTRA_PARTICIPANT_3_GRPC_HEALTHCHECK_PORT}
72
- }
73
- http-ledger-api.port = ${EXTRA_PARTICIPANT_3_JSON_API_PORT}
74
- admin-api.port = ${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}
75
- ledger-api.port = ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
76
- ledger-api {
77
- auth-services = [{
78
- type = unsafe-jwt-hmac-256
79
- target-audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
80
- secret = "unsafe"
81
- }]
82
-
83
- user-management-service.additional-admin-user-id = "${EXTRA_VALIDATOR_3_USER_NAME}"
84
- }
85
- }
86
-
87
- ports:
88
- - "${EXTRA_PARTICIPANT_1_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}"
89
- - "${EXTRA_PARTICIPANT_1_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}"
90
- - "${EXTRA_PARTICIPANT_1_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_JSON_API_PORT}"
91
- - "${EXTRA_PARTICIPANT_2_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}"
92
- - "${EXTRA_PARTICIPANT_2_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}"
93
- - "${EXTRA_PARTICIPANT_2_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_JSON_API_PORT}"
94
- - "${EXTRA_PARTICIPANT_3_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}"
95
- - "${EXTRA_PARTICIPANT_3_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}"
96
- - "${EXTRA_PARTICIPANT_3_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_JSON_API_PORT}"
97
- splice:
98
- env_file:
99
- - ${START_LOCAL_GENERATED_DIR}/extra-participants.env
100
- environment:
101
- ADDITIONAL_CONFIG_EXTRA_VALIDATORS: |
102
- canton.validator-apps.extra-1-validator_backend = $${_validator_backend} {
103
- onboarding.secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}"
104
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-1.json"
105
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_1_DB}"
106
- admin-api.port = ${EXTRA_VALIDATOR_1_ADMIN_API_PORT}
107
- canton-identifier-config.participant = extra-1
108
- participant-client {
109
- admin-api.port = ${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}
110
- ledger-api {
111
- client-config.port = ${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}
112
- auth-config = {
113
- type = "self-signed"
114
- user = "${EXTRA_VALIDATOR_1_USER_NAME}"
115
- audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
116
- secret = "unsafe"
117
- }
118
- }
119
- }
120
- auth = {
121
- algorithm = "hs-256-unsafe"
122
- audience = "${EXTRA_VALIDATOR_1_AUTH_AUDIENCE}"
123
- secret = "unsafe"
124
- }
125
- ledger-api-user = "${EXTRA_VALIDATOR_1_USER_NAME}"
126
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_1_WALLET_ADMIN_USER_NAME}"
127
- validator-party-hint = "${EXTRA_VALIDATOR_1_PARTY_HINT}"
128
-
129
- domains.global.buy-extra-traffic {
130
- min-topup-interval = $${?MIN_TRAFFIC_TOPUP_INTERVAL}
131
- target-throughput = $${?TARGET_TRAFFIC_THROUGHPUT}
132
- }
133
- }
134
-
135
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}" }
136
-
137
- canton.validator-apps.extra-2-validator_backend = $${_validator_backend} {
138
- onboarding.secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}"
139
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-2.json"
140
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_2_DB}"
141
- admin-api.port = ${EXTRA_VALIDATOR_2_ADMIN_API_PORT}
142
- canton-identifier-config.participant = extra-2
143
- participant-client {
144
- admin-api.port = ${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}
145
- ledger-api {
146
- client-config.port = ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
147
- auth-config = {
148
- type = "self-signed"
149
- user = "${EXTRA_VALIDATOR_2_USER_NAME}"
150
- audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
151
- secret = "unsafe"
152
- }
153
- }
154
- }
155
- auth = {
156
- algorithm = "hs-256-unsafe"
157
- audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
158
- secret = "unsafe"
159
- }
160
- ledger-api-user = "${EXTRA_VALIDATOR_2_USER_NAME}"
161
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_2_WALLET_ADMIN_USER_NAME}"
162
- validator-party-hint = "${EXTRA_VALIDATOR_2_PARTY_HINT}"
163
-
164
- domains.global.buy-extra-traffic {
165
- min-topup-interval = $${?MIN_TRAFFIC_TOPUP_INTERVAL}
166
- target-throughput = $${?TARGET_TRAFFIC_THROUGHPUT}
167
- }
168
- }
169
-
170
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}" }
171
-
172
- canton.validator-apps.extra-3-validator_backend = $${_validator_backend} {
173
- onboarding.secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}"
174
- domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-3.json"
175
- storage.config.properties.databaseName = "${EXTRA_VALIDATOR_3_DB}"
176
- admin-api.port = ${EXTRA_VALIDATOR_3_ADMIN_API_PORT}
177
- canton-identifier-config.participant = extra-3
178
- participant-client {
179
- admin-api.port = ${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}
180
- ledger-api {
181
- client-config.port = ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
182
- auth-config = {
183
- type = "self-signed"
184
- user = "${EXTRA_VALIDATOR_3_USER_NAME}"
185
- audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
186
- secret = "unsafe"
187
- }
188
- }
189
- }
190
- auth = {
191
- algorithm = "hs-256-unsafe"
192
- audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
193
- secret = "unsafe"
194
- }
195
- ledger-api-user = "${EXTRA_VALIDATOR_3_USER_NAME}"
196
- validator-wallet-users.0 = "${EXTRA_VALIDATOR_3_WALLET_ADMIN_USER_NAME}"
197
- validator-party-hint = "${EXTRA_VALIDATOR_3_PARTY_HINT}"
198
-
199
- domains.global.buy-extra-traffic {
200
- min-topup-interval = $${?MIN_TRAFFIC_TOPUP_INTERVAL}
201
- target-throughput = $${?TARGET_TRAFFIC_THROUGHPUT}
202
- }
203
- }
204
-
205
- canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}" }
206
-
207
- ports:
208
- - "${EXTRA_VALIDATOR_1_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_1_ADMIN_API_PORT}"
209
- - "${EXTRA_VALIDATOR_2_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_2_ADMIN_API_PORT}"
210
- - "${EXTRA_VALIDATOR_3_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_3_ADMIN_API_PORT}"
211
- postgres-pqs-extra-1:
212
- image: "postgres:${POSTGRES_VERSION}"
213
- container_name: postgres-pqs-extra-1
214
- volumes:
215
- - postgres-pqs-extra-1:/var/lib/postgresql/data
216
- - ${LOCALNET_DIR}/docker/postgres/postgres-entrypoint.sh:/postgres-entrypoint.sh
217
- environment:
218
- POSTGRES_USER: ${DB_USER}
219
- POSTGRES_PASSWORD: ${DB_PASSWORD}
220
- POSTGRES_DB: postgres
221
- CREATE_DATABASE_EXTRA_PQS_1: ${EXTRA_PQS_1_POSTGRES_DB}
222
- ports:
223
- - "${EXTRA_PQS_1_POSTGRES_PUBLISHED_PORT}:5432"
224
- entrypoint: /postgres-entrypoint.sh
225
- healthcheck:
226
- test: "pg_isready -U ${DB_USER} -d postgres"
227
- interval: 10s
228
- timeout: 3s
229
- retries: 3
230
- start_period: 30s
231
- user: "postgres"
232
- command:
233
- - postgres
234
- - -c
235
- - max_connections=1000
236
- pqs-extra-1:
237
- image: ${SCRIBE_IMAGE}:${SCRIBE_VERSION}
238
- container_name: pqs-extra-1
239
- environment:
240
- SCRIBE_SOURCE_LEDGER_HOST: canton
241
- SCRIBE_SOURCE_LEDGER_PORT: ${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}
242
- SCRIBE_SOURCE_LEDGER_AUTH: OAuth
243
- SCRIBE_TARGET_POSTGRES_HOST: postgres-pqs-extra-1
244
- SCRIBE_TARGET_POSTGRES_PORT: 5432
245
- SCRIBE_TARGET_POSTGRES_DATABASE: ${EXTRA_PQS_1_POSTGRES_DB}
246
- SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
247
- SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
248
- SCRIBE_CONFIG: /onboarding/extra-1-pqs.conf
249
- volumes:
250
- - onboarding:/onboarding
251
- command:
252
- - pipeline
253
- - ledger
254
- - postgres-document
255
- depends_on:
256
- canton:
257
- condition: service_healthy
258
- splice-onboarding:
259
- condition: service_healthy
260
- postgres-pqs-extra-1:
261
- condition: service_healthy
262
- restart: on-failure:100
263
- postgres-pqs-extra-2:
264
- image: "postgres:${POSTGRES_VERSION}"
265
- container_name: postgres-pqs-extra-2
266
- volumes:
267
- - postgres-pqs-extra-2:/var/lib/postgresql/data
268
- - ${LOCALNET_DIR}/docker/postgres/postgres-entrypoint.sh:/postgres-entrypoint.sh
269
- environment:
270
- POSTGRES_USER: ${DB_USER}
271
- POSTGRES_PASSWORD: ${DB_PASSWORD}
272
- POSTGRES_DB: postgres
273
- CREATE_DATABASE_EXTRA_PQS_2: ${EXTRA_PQS_2_POSTGRES_DB}
274
- ports:
275
- - "${EXTRA_PQS_2_POSTGRES_PUBLISHED_PORT}:5432"
276
- entrypoint: /postgres-entrypoint.sh
277
- healthcheck:
278
- test: "pg_isready -U ${DB_USER} -d postgres"
279
- interval: 10s
280
- timeout: 3s
281
- retries: 3
282
- start_period: 30s
283
- user: "postgres"
284
- command:
285
- - postgres
286
- - -c
287
- - max_connections=1000
288
- pqs-extra-2:
289
- image: ${SCRIBE_IMAGE}:${SCRIBE_VERSION}
290
- container_name: pqs-extra-2
291
- environment:
292
- SCRIBE_SOURCE_LEDGER_HOST: canton
293
- SCRIBE_SOURCE_LEDGER_PORT: ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
294
- SCRIBE_SOURCE_LEDGER_AUTH: OAuth
295
- SCRIBE_TARGET_POSTGRES_HOST: postgres-pqs-extra-2
296
- SCRIBE_TARGET_POSTGRES_PORT: 5432
297
- SCRIBE_TARGET_POSTGRES_DATABASE: ${EXTRA_PQS_2_POSTGRES_DB}
298
- SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
299
- SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
300
- SCRIBE_CONFIG: /onboarding/extra-2-pqs.conf
301
- volumes:
302
- - onboarding:/onboarding
303
- command:
304
- - pipeline
305
- - ledger
306
- - postgres-document
307
- depends_on:
308
- canton:
309
- condition: service_healthy
310
- splice-onboarding:
311
- condition: service_healthy
312
- postgres-pqs-extra-2:
313
- condition: service_healthy
314
- restart: on-failure:100
315
- postgres-pqs-extra-3:
316
- image: "postgres:${POSTGRES_VERSION}"
317
- container_name: postgres-pqs-extra-3
318
- volumes:
319
- - postgres-pqs-extra-3:/var/lib/postgresql/data
320
- - ${LOCALNET_DIR}/docker/postgres/postgres-entrypoint.sh:/postgres-entrypoint.sh
321
- environment:
322
- POSTGRES_USER: ${DB_USER}
323
- POSTGRES_PASSWORD: ${DB_PASSWORD}
324
- POSTGRES_DB: postgres
325
- CREATE_DATABASE_EXTRA_PQS_3: ${EXTRA_PQS_3_POSTGRES_DB}
326
- ports:
327
- - "${EXTRA_PQS_3_POSTGRES_PUBLISHED_PORT}:5432"
328
- entrypoint: /postgres-entrypoint.sh
329
- healthcheck:
330
- test: "pg_isready -U ${DB_USER} -d postgres"
331
- interval: 10s
332
- timeout: 3s
333
- retries: 3
334
- start_period: 30s
335
- user: "postgres"
336
- command:
337
- - postgres
338
- - -c
339
- - max_connections=1000
340
- pqs-extra-3:
341
- image: ${SCRIBE_IMAGE}:${SCRIBE_VERSION}
342
- container_name: pqs-extra-3
343
- environment:
344
- SCRIBE_SOURCE_LEDGER_HOST: canton
345
- SCRIBE_SOURCE_LEDGER_PORT: ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
346
- SCRIBE_SOURCE_LEDGER_AUTH: OAuth
347
- SCRIBE_TARGET_POSTGRES_HOST: postgres-pqs-extra-3
348
- SCRIBE_TARGET_POSTGRES_PORT: 5432
349
- SCRIBE_TARGET_POSTGRES_DATABASE: ${EXTRA_PQS_3_POSTGRES_DB}
350
- SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
351
- SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
352
- SCRIBE_CONFIG: /onboarding/extra-3-pqs.conf
353
- volumes:
354
- - onboarding:/onboarding
355
- command:
356
- - pipeline
357
- - ledger
358
- - postgres-document
359
- depends_on:
360
- canton:
361
- condition: service_healthy
362
- splice-onboarding:
363
- condition: service_healthy
364
- postgres-pqs-extra-3:
365
- condition: service_healthy
366
- restart: on-failure:100
@@ -1,88 +0,0 @@
1
- START_LOCAL_GENERATED_DIR=/home/helena/env/daml/typescript-sdk/node/.generated/start-local
2
- CREATE_DATABASE_EXTRA_1=participant-extra-1
3
- CREATE_DATABASE_EXTRA_VALIDATOR_1=validator-extra-1
4
- CREATE_DATABASE_EXTRA_PQS_1=pqs-extra-1
5
- EXTRA_PARTICIPANT_1_NAME=extra-1
6
- EXTRA_PARTICIPANT_1_DB=participant-extra-1
7
- EXTRA_PARTICIPANT_1_PARTY_HINT=extra_1_quickstart-helena-1
8
- EXTRA_PARTICIPANT_1_LEDGER_API_PORT=5901
9
- EXTRA_PARTICIPANT_1_ADMIN_API_PORT=5902
10
- EXTRA_PARTICIPANT_1_JSON_API_PORT=5975
11
- EXTRA_PARTICIPANT_1_HTTP_HEALTHCHECK_PORT=5900
12
- EXTRA_PARTICIPANT_1_GRPC_HEALTHCHECK_PORT=5961
13
- EXTRA_PARTICIPANT_1_LEDGER_API_PUBLISHED_PORT=5901
14
- EXTRA_PARTICIPANT_1_ADMIN_API_PUBLISHED_PORT=5902
15
- EXTRA_PARTICIPANT_1_JSON_API_PUBLISHED_PORT=5975
16
- EXTRA_VALIDATOR_1_DB=validator-extra-1
17
- EXTRA_VALIDATOR_1_PARTY_HINT=validator_1_quickstart-helena-1
18
- EXTRA_VALIDATOR_1_ONBOARDING_SECRET=extra-1-validator-onboarding-secret
19
- EXTRA_VALIDATOR_1_ADMIN_API_PORT=5903
20
- EXTRA_VALIDATOR_1_ADMIN_API_PUBLISHED_PORT=5903
21
- EXTRA_VALIDATOR_1_USER_NAME=ledger-api-user
22
- EXTRA_VALIDATOR_1_WALLET_ADMIN_USER_NAME=extra-1
23
- EXTRA_VALIDATOR_1_AUTH_AUDIENCE=https://canton.network.global
24
- EXTRA_VALIDATOR_1_AUTH_MODE=shared-secret
25
- EXTRA_PQS_1_NAME=pqs-extra-1
26
- EXTRA_PQS_1_USER_NAME=extra-1-pqs-user
27
- EXTRA_PQS_1_POSTGRES_NAME=postgres-pqs-extra-1
28
- EXTRA_PQS_1_POSTGRES_DB=pqs-extra-1
29
- EXTRA_PQS_1_POSTGRES_PUBLISHED_PORT=5541
30
- EXTRA_PQS_1_CONFIG_FILE=extra-1-pqs.conf
31
- CREATE_DATABASE_EXTRA_2=participant-extra-2
32
- CREATE_DATABASE_EXTRA_VALIDATOR_2=validator-extra-2
33
- CREATE_DATABASE_EXTRA_PQS_2=pqs-extra-2
34
- EXTRA_PARTICIPANT_2_NAME=extra-2
35
- EXTRA_PARTICIPANT_2_DB=participant-extra-2
36
- EXTRA_PARTICIPANT_2_PARTY_HINT=extra_2_quickstart-helena-1
37
- EXTRA_PARTICIPANT_2_LEDGER_API_PORT=6901
38
- EXTRA_PARTICIPANT_2_ADMIN_API_PORT=6902
39
- EXTRA_PARTICIPANT_2_JSON_API_PORT=6975
40
- EXTRA_PARTICIPANT_2_HTTP_HEALTHCHECK_PORT=6900
41
- EXTRA_PARTICIPANT_2_GRPC_HEALTHCHECK_PORT=6961
42
- EXTRA_PARTICIPANT_2_LEDGER_API_PUBLISHED_PORT=6901
43
- EXTRA_PARTICIPANT_2_ADMIN_API_PUBLISHED_PORT=6902
44
- EXTRA_PARTICIPANT_2_JSON_API_PUBLISHED_PORT=6975
45
- EXTRA_VALIDATOR_2_DB=validator-extra-2
46
- EXTRA_VALIDATOR_2_PARTY_HINT=validator_2_quickstart-helena-1
47
- EXTRA_VALIDATOR_2_ONBOARDING_SECRET=extra-2-validator-onboarding-secret
48
- EXTRA_VALIDATOR_2_ADMIN_API_PORT=6903
49
- EXTRA_VALIDATOR_2_ADMIN_API_PUBLISHED_PORT=6903
50
- EXTRA_VALIDATOR_2_USER_NAME=ledger-api-user
51
- EXTRA_VALIDATOR_2_WALLET_ADMIN_USER_NAME=extra-2
52
- EXTRA_VALIDATOR_2_AUTH_AUDIENCE=https://canton.network.global
53
- EXTRA_VALIDATOR_2_AUTH_MODE=shared-secret
54
- EXTRA_PQS_2_NAME=pqs-extra-2
55
- EXTRA_PQS_2_USER_NAME=extra-2-pqs-user
56
- EXTRA_PQS_2_POSTGRES_NAME=postgres-pqs-extra-2
57
- EXTRA_PQS_2_POSTGRES_DB=pqs-extra-2
58
- EXTRA_PQS_2_POSTGRES_PUBLISHED_PORT=5542
59
- EXTRA_PQS_2_CONFIG_FILE=extra-2-pqs.conf
60
- CREATE_DATABASE_EXTRA_3=participant-extra-3
61
- CREATE_DATABASE_EXTRA_VALIDATOR_3=validator-extra-3
62
- CREATE_DATABASE_EXTRA_PQS_3=pqs-extra-3
63
- EXTRA_PARTICIPANT_3_NAME=extra-3
64
- EXTRA_PARTICIPANT_3_DB=participant-extra-3
65
- EXTRA_PARTICIPANT_3_PARTY_HINT=extra_3_quickstart-helena-1
66
- EXTRA_PARTICIPANT_3_LEDGER_API_PORT=7901
67
- EXTRA_PARTICIPANT_3_ADMIN_API_PORT=7902
68
- EXTRA_PARTICIPANT_3_JSON_API_PORT=7975
69
- EXTRA_PARTICIPANT_3_HTTP_HEALTHCHECK_PORT=7900
70
- EXTRA_PARTICIPANT_3_GRPC_HEALTHCHECK_PORT=7961
71
- EXTRA_PARTICIPANT_3_LEDGER_API_PUBLISHED_PORT=7901
72
- EXTRA_PARTICIPANT_3_ADMIN_API_PUBLISHED_PORT=7902
73
- EXTRA_PARTICIPANT_3_JSON_API_PUBLISHED_PORT=7975
74
- EXTRA_VALIDATOR_3_DB=validator-extra-3
75
- EXTRA_VALIDATOR_3_PARTY_HINT=validator_3_quickstart-helena-1
76
- EXTRA_VALIDATOR_3_ONBOARDING_SECRET=extra-3-validator-onboarding-secret
77
- EXTRA_VALIDATOR_3_ADMIN_API_PORT=7903
78
- EXTRA_VALIDATOR_3_ADMIN_API_PUBLISHED_PORT=7903
79
- EXTRA_VALIDATOR_3_USER_NAME=ledger-api-user
80
- EXTRA_VALIDATOR_3_WALLET_ADMIN_USER_NAME=extra-3
81
- EXTRA_VALIDATOR_3_AUTH_AUDIENCE=https://canton.network.global
82
- EXTRA_VALIDATOR_3_AUTH_MODE=shared-secret
83
- EXTRA_PQS_3_NAME=pqs-extra-3
84
- EXTRA_PQS_3_USER_NAME=extra-3-pqs-user
85
- EXTRA_PQS_3_POSTGRES_NAME=postgres-pqs-extra-3
86
- EXTRA_PQS_3_POSTGRES_DB=pqs-extra-3
87
- EXTRA_PQS_3_POSTGRES_PUBLISHED_PORT=5543
88
- EXTRA_PQS_3_CONFIG_FILE=extra-3-pqs.conf