@distrohelena/canton-typescript-sdk 0.1.22 → 0.1.24

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
@@ -1,11 +1,10 @@
1
1
  # Canton TypeScript SDK
2
2
 
3
- TypeScript SDK for Canton with:
4
-
5
- - a shared `CantonClient`
6
- - `grpc` and `json` transports
7
- - `grpc`-only external signing
8
- - gRPC Ledger API service boundaries as the public SDK shape
3
+ TypeScript SDK for Canton with a shared `CantonClient`, gRPC and JSON
4
+ transports, gRPC Ledger API-shaped service boundaries, PQS-backed relational
5
+ queries, external-party lifecycle and signing, authenticated and TLS-secured
6
+ channels, and experimental tooling for invariant testing, DAML-LF inspection,
7
+ interface generation, and replay debugging.
9
8
 
10
9
  ## Install
11
10
 
@@ -22,6 +22,54 @@ canton.participants.extra-1 = $${_participant} {
22
22
  }
23
23
  }
24
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
+
25
73
  canton.participants.extra-1.ledger-api.auth-services = [
26
74
  {
27
75
  type = unsafe-jwt-hmac-256
@@ -35,3 +83,62 @@ canton.participants.extra-1.ledger-api.auth-services = [
35
83
  }
36
84
  ]
37
85
 
86
+ canton.participants.extra-2.ledger-api.auth-services = [
87
+ {
88
+ type = unsafe-jwt-hmac-256
89
+ target-audience = "https://canton.network.global"
90
+ secret = "unsafe"
91
+ },
92
+ {
93
+ type = jwt-es-256-crt
94
+ certificate = "/app/es256-certificate.pem"
95
+ target-audience = "https://canton.network.global/es256"
96
+ }
97
+ ]
98
+
99
+ canton.participants.extra-3.ledger-api.auth-services = [
100
+ {
101
+ type = unsafe-jwt-hmac-256
102
+ target-audience = "https://canton.network.global"
103
+ secret = "unsafe"
104
+ },
105
+ {
106
+ type = jwt-es-256-crt
107
+ certificate = "/app/es256-certificate.pem"
108
+ target-audience = "https://canton.network.global/es256"
109
+ }
110
+ ]
111
+
112
+ canton.participants.extra-1.ledger-api.tls {
113
+ cert-chain-file = "/app/localnet-tls/server.crt"
114
+ private-key-file = "/app/localnet-tls/server.key"
115
+ trust-collection-file = "/app/localnet-tls/ca.crt"
116
+ }
117
+ canton.participants.extra-1.admin-api.tls {
118
+ cert-chain-file = "/app/localnet-tls/server.crt"
119
+ private-key-file = "/app/localnet-tls/server.key"
120
+ trust-collection-file = "/app/localnet-tls/ca.crt"
121
+ }
122
+
123
+ canton.participants.extra-2.ledger-api.tls {
124
+ cert-chain-file = "/app/localnet-tls/server.crt"
125
+ private-key-file = "/app/localnet-tls/server.key"
126
+ trust-collection-file = "/app/localnet-tls/ca.crt"
127
+ }
128
+ canton.participants.extra-2.admin-api.tls {
129
+ cert-chain-file = "/app/localnet-tls/server.crt"
130
+ private-key-file = "/app/localnet-tls/server.key"
131
+ trust-collection-file = "/app/localnet-tls/ca.crt"
132
+ }
133
+
134
+ canton.participants.extra-3.ledger-api.tls {
135
+ cert-chain-file = "/app/localnet-tls/server.crt"
136
+ private-key-file = "/app/localnet-tls/server.key"
137
+ trust-collection-file = "/app/localnet-tls/ca.crt"
138
+ }
139
+ canton.participants.extra-3.admin-api.tls {
140
+ cert-chain-file = "/app/localnet-tls/server.crt"
141
+ private-key-file = "/app/localnet-tls/server.key"
142
+ trust-collection-file = "/app/localnet-tls/ca.crt"
143
+ }
144
+
@@ -33,3 +33,88 @@ canton.validator-apps.extra-1-validator_backend = $${_validator_backend} {
33
33
 
34
34
  canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}" }
35
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
+
106
+ canton.validator-apps.extra-1-validator_backend.participant-client {
107
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
108
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
109
+ }
110
+
111
+ canton.validator-apps.extra-2-validator_backend.participant-client {
112
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
113
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
114
+ }
115
+
116
+ canton.validator-apps.extra-3-validator_backend.participant-client {
117
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
118
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
119
+ }
120
+
@@ -1,5 +1,7 @@
1
1
  volumes:
2
2
  postgres-pqs-extra-1:
3
+ postgres-pqs-extra-2:
4
+ postgres-pqs-extra-3:
3
5
 
4
6
  services:
5
7
  postgres:
@@ -34,6 +36,54 @@ services:
34
36
  }
35
37
  }
36
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
+
37
87
  canton.participants.extra-1.ledger-api.auth-services = [
38
88
  {
39
89
  type = unsafe-jwt-hmac-256
@@ -47,10 +97,75 @@ services:
47
97
  }
48
98
  ]
49
99
 
100
+ canton.participants.extra-2.ledger-api.auth-services = [
101
+ {
102
+ type = unsafe-jwt-hmac-256
103
+ target-audience = "https://canton.network.global"
104
+ secret = "unsafe"
105
+ },
106
+ {
107
+ type = jwt-es-256-crt
108
+ certificate = "/app/es256-certificate.pem"
109
+ target-audience = "https://canton.network.global/es256"
110
+ }
111
+ ]
112
+
113
+ canton.participants.extra-3.ledger-api.auth-services = [
114
+ {
115
+ type = unsafe-jwt-hmac-256
116
+ target-audience = "https://canton.network.global"
117
+ secret = "unsafe"
118
+ },
119
+ {
120
+ type = jwt-es-256-crt
121
+ certificate = "/app/es256-certificate.pem"
122
+ target-audience = "https://canton.network.global/es256"
123
+ }
124
+ ]
125
+
126
+ canton.participants.extra-1.ledger-api.tls {
127
+ cert-chain-file = "/app/localnet-tls/server.crt"
128
+ private-key-file = "/app/localnet-tls/server.key"
129
+ trust-collection-file = "/app/localnet-tls/ca.crt"
130
+ }
131
+ canton.participants.extra-1.admin-api.tls {
132
+ cert-chain-file = "/app/localnet-tls/server.crt"
133
+ private-key-file = "/app/localnet-tls/server.key"
134
+ trust-collection-file = "/app/localnet-tls/ca.crt"
135
+ }
136
+
137
+ canton.participants.extra-2.ledger-api.tls {
138
+ cert-chain-file = "/app/localnet-tls/server.crt"
139
+ private-key-file = "/app/localnet-tls/server.key"
140
+ trust-collection-file = "/app/localnet-tls/ca.crt"
141
+ }
142
+ canton.participants.extra-2.admin-api.tls {
143
+ cert-chain-file = "/app/localnet-tls/server.crt"
144
+ private-key-file = "/app/localnet-tls/server.key"
145
+ trust-collection-file = "/app/localnet-tls/ca.crt"
146
+ }
147
+
148
+ canton.participants.extra-3.ledger-api.tls {
149
+ cert-chain-file = "/app/localnet-tls/server.crt"
150
+ private-key-file = "/app/localnet-tls/server.key"
151
+ trust-collection-file = "/app/localnet-tls/ca.crt"
152
+ }
153
+ canton.participants.extra-3.admin-api.tls {
154
+ cert-chain-file = "/app/localnet-tls/server.crt"
155
+ private-key-file = "/app/localnet-tls/server.key"
156
+ trust-collection-file = "/app/localnet-tls/ca.crt"
157
+ }
158
+
50
159
  ports:
51
160
  - "${EXTRA_PARTICIPANT_1_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_LEDGER_API_PORT}"
52
161
  - "${EXTRA_PARTICIPANT_1_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_ADMIN_API_PORT}"
53
162
  - "${EXTRA_PARTICIPANT_1_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_1_JSON_API_PORT}"
163
+ - "${EXTRA_PARTICIPANT_2_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}"
164
+ - "${EXTRA_PARTICIPANT_2_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}"
165
+ - "${EXTRA_PARTICIPANT_2_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_2_JSON_API_PORT}"
166
+ - "${EXTRA_PARTICIPANT_3_LEDGER_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}"
167
+ - "${EXTRA_PARTICIPANT_3_ADMIN_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}"
168
+ - "${EXTRA_PARTICIPANT_3_JSON_API_PUBLISHED_PORT}:${EXTRA_PARTICIPANT_3_JSON_API_PORT}"
54
169
  splice:
55
170
  env_file:
56
171
  - ${START_LOCAL_GENERATED_DIR}/extra-participants.env
@@ -91,8 +206,95 @@ services:
91
206
 
92
207
  canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_1_ONBOARDING_SECRET}" }
93
208
 
209
+ canton.validator-apps.extra-2-validator_backend = $${_validator_backend} {
210
+ onboarding.secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}"
211
+ domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-2.json"
212
+ storage.config.properties.databaseName = "${EXTRA_VALIDATOR_2_DB}"
213
+ admin-api.port = ${EXTRA_VALIDATOR_2_ADMIN_API_PORT}
214
+ canton-identifier-config.participant = extra-2
215
+ participant-client {
216
+ admin-api.port = ${EXTRA_PARTICIPANT_2_ADMIN_API_PORT}
217
+ ledger-api {
218
+ client-config.port = ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
219
+ auth-config = {
220
+ type = "self-signed"
221
+ user = "${EXTRA_VALIDATOR_2_USER_NAME}"
222
+ audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
223
+ secret = "unsafe"
224
+ }
225
+ }
226
+ }
227
+ auth = {
228
+ algorithm = "hs-256-unsafe"
229
+ audience = "${EXTRA_VALIDATOR_2_AUTH_AUDIENCE}"
230
+ secret = "unsafe"
231
+ }
232
+ ledger-api-user = "${EXTRA_VALIDATOR_2_USER_NAME}"
233
+ validator-wallet-users.0 = "${EXTRA_VALIDATOR_2_WALLET_ADMIN_USER_NAME}"
234
+ validator-party-hint = "${EXTRA_VALIDATOR_2_PARTY_HINT}"
235
+
236
+ domains.global.buy-extra-traffic {
237
+ min-topup-interval = $${?MIN_TRAFFIC_TOPUP_INTERVAL}
238
+ target-throughput = $${?TARGET_TRAFFIC_THROUGHPUT}
239
+ }
240
+ }
241
+
242
+ canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_2_ONBOARDING_SECRET}" }
243
+
244
+ canton.validator-apps.extra-3-validator_backend = $${_validator_backend} {
245
+ onboarding.secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}"
246
+ domain-migration-dump-path = "/domain-upgrade-dump/domain_migration_dump-extra-3.json"
247
+ storage.config.properties.databaseName = "${EXTRA_VALIDATOR_3_DB}"
248
+ admin-api.port = ${EXTRA_VALIDATOR_3_ADMIN_API_PORT}
249
+ canton-identifier-config.participant = extra-3
250
+ participant-client {
251
+ admin-api.port = ${EXTRA_PARTICIPANT_3_ADMIN_API_PORT}
252
+ ledger-api {
253
+ client-config.port = ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
254
+ auth-config = {
255
+ type = "self-signed"
256
+ user = "${EXTRA_VALIDATOR_3_USER_NAME}"
257
+ audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
258
+ secret = "unsafe"
259
+ }
260
+ }
261
+ }
262
+ auth = {
263
+ algorithm = "hs-256-unsafe"
264
+ audience = "${EXTRA_VALIDATOR_3_AUTH_AUDIENCE}"
265
+ secret = "unsafe"
266
+ }
267
+ ledger-api-user = "${EXTRA_VALIDATOR_3_USER_NAME}"
268
+ validator-wallet-users.0 = "${EXTRA_VALIDATOR_3_WALLET_ADMIN_USER_NAME}"
269
+ validator-party-hint = "${EXTRA_VALIDATOR_3_PARTY_HINT}"
270
+
271
+ domains.global.buy-extra-traffic {
272
+ min-topup-interval = $${?MIN_TRAFFIC_TOPUP_INTERVAL}
273
+ target-throughput = $${?TARGET_TRAFFIC_THROUGHPUT}
274
+ }
275
+ }
276
+
277
+ canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}" }
278
+
279
+ canton.validator-apps.extra-1-validator_backend.participant-client {
280
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
281
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
282
+ }
283
+
284
+ canton.validator-apps.extra-2-validator_backend.participant-client {
285
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
286
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
287
+ }
288
+
289
+ canton.validator-apps.extra-3-validator_backend.participant-client {
290
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
291
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
292
+ }
293
+
94
294
  ports:
95
295
  - "${EXTRA_VALIDATOR_1_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_1_ADMIN_API_PORT}"
296
+ - "${EXTRA_VALIDATOR_2_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_2_ADMIN_API_PORT}"
297
+ - "${EXTRA_VALIDATOR_3_ADMIN_API_PUBLISHED_PORT}:${EXTRA_VALIDATOR_3_ADMIN_API_PORT}"
96
298
  postgres-pqs-extra-1:
97
299
  image: "postgres:${POSTGRES_VERSION}"
98
300
  container_name: postgres-pqs-extra-1
@@ -131,8 +333,10 @@ services:
131
333
  SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
132
334
  SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
133
335
  SCRIBE_CONFIG: /onboarding/extra-1-pqs.conf
336
+ SCRIBE_SOURCE_LEDGER_TLS_CAFILE: /app/localnet-tls/ca.crt
134
337
  volumes:
135
338
  - onboarding:/onboarding
339
+ - "/home/helena/env/daml/typescript-sdk/.generated/localnet-tls/ca.crt:/app/localnet-tls/ca.crt:ro"
136
340
  command:
137
341
  - pipeline
138
342
  - ledger
@@ -145,3 +349,111 @@ services:
145
349
  postgres-pqs-extra-1:
146
350
  condition: service_healthy
147
351
  restart: on-failure:100
352
+ postgres-pqs-extra-2:
353
+ image: "postgres:${POSTGRES_VERSION}"
354
+ container_name: postgres-pqs-extra-2
355
+ volumes:
356
+ - postgres-pqs-extra-2:/var/lib/postgresql/data
357
+ - ${LOCALNET_DIR}/docker/postgres/postgres-entrypoint.sh:/postgres-entrypoint.sh
358
+ environment:
359
+ POSTGRES_USER: ${DB_USER}
360
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
361
+ POSTGRES_DB: postgres
362
+ CREATE_DATABASE_EXTRA_PQS_2: ${EXTRA_PQS_2_POSTGRES_DB}
363
+ ports:
364
+ - "${EXTRA_PQS_2_POSTGRES_PUBLISHED_PORT}:5432"
365
+ entrypoint: /postgres-entrypoint.sh
366
+ healthcheck:
367
+ test: "pg_isready -U ${DB_USER} -d postgres"
368
+ interval: 10s
369
+ timeout: 3s
370
+ retries: 3
371
+ start_period: 30s
372
+ user: "postgres"
373
+ command:
374
+ - postgres
375
+ - -c
376
+ - max_connections=1000
377
+ pqs-extra-2:
378
+ image: ${SCRIBE_IMAGE}:${SCRIBE_VERSION}
379
+ container_name: pqs-extra-2
380
+ environment:
381
+ SCRIBE_SOURCE_LEDGER_HOST: canton
382
+ SCRIBE_SOURCE_LEDGER_PORT: ${EXTRA_PARTICIPANT_2_LEDGER_API_PORT}
383
+ SCRIBE_SOURCE_LEDGER_AUTH: OAuth
384
+ SCRIBE_TARGET_POSTGRES_HOST: postgres-pqs-extra-2
385
+ SCRIBE_TARGET_POSTGRES_PORT: 5432
386
+ SCRIBE_TARGET_POSTGRES_DATABASE: ${EXTRA_PQS_2_POSTGRES_DB}
387
+ SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
388
+ SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
389
+ SCRIBE_CONFIG: /onboarding/extra-2-pqs.conf
390
+ SCRIBE_SOURCE_LEDGER_TLS_CAFILE: /app/localnet-tls/ca.crt
391
+ volumes:
392
+ - onboarding:/onboarding
393
+ - "/home/helena/env/daml/typescript-sdk/.generated/localnet-tls/ca.crt:/app/localnet-tls/ca.crt:ro"
394
+ command:
395
+ - pipeline
396
+ - ledger
397
+ - postgres-document
398
+ depends_on:
399
+ canton:
400
+ condition: service_healthy
401
+ splice-onboarding:
402
+ condition: service_healthy
403
+ postgres-pqs-extra-2:
404
+ condition: service_healthy
405
+ restart: on-failure:100
406
+ postgres-pqs-extra-3:
407
+ image: "postgres:${POSTGRES_VERSION}"
408
+ container_name: postgres-pqs-extra-3
409
+ volumes:
410
+ - postgres-pqs-extra-3:/var/lib/postgresql/data
411
+ - ${LOCALNET_DIR}/docker/postgres/postgres-entrypoint.sh:/postgres-entrypoint.sh
412
+ environment:
413
+ POSTGRES_USER: ${DB_USER}
414
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
415
+ POSTGRES_DB: postgres
416
+ CREATE_DATABASE_EXTRA_PQS_3: ${EXTRA_PQS_3_POSTGRES_DB}
417
+ ports:
418
+ - "${EXTRA_PQS_3_POSTGRES_PUBLISHED_PORT}:5432"
419
+ entrypoint: /postgres-entrypoint.sh
420
+ healthcheck:
421
+ test: "pg_isready -U ${DB_USER} -d postgres"
422
+ interval: 10s
423
+ timeout: 3s
424
+ retries: 3
425
+ start_period: 30s
426
+ user: "postgres"
427
+ command:
428
+ - postgres
429
+ - -c
430
+ - max_connections=1000
431
+ pqs-extra-3:
432
+ image: ${SCRIBE_IMAGE}:${SCRIBE_VERSION}
433
+ container_name: pqs-extra-3
434
+ environment:
435
+ SCRIBE_SOURCE_LEDGER_HOST: canton
436
+ SCRIBE_SOURCE_LEDGER_PORT: ${EXTRA_PARTICIPANT_3_LEDGER_API_PORT}
437
+ SCRIBE_SOURCE_LEDGER_AUTH: OAuth
438
+ SCRIBE_TARGET_POSTGRES_HOST: postgres-pqs-extra-3
439
+ SCRIBE_TARGET_POSTGRES_PORT: 5432
440
+ SCRIBE_TARGET_POSTGRES_DATABASE: ${EXTRA_PQS_3_POSTGRES_DB}
441
+ SCRIBE_TARGET_POSTGRES_USERNAME: ${DB_USER}
442
+ SCRIBE_TARGET_POSTGRES_PASSWORD: ${DB_PASSWORD}
443
+ SCRIBE_CONFIG: /onboarding/extra-3-pqs.conf
444
+ SCRIBE_SOURCE_LEDGER_TLS_CAFILE: /app/localnet-tls/ca.crt
445
+ volumes:
446
+ - onboarding:/onboarding
447
+ - "/home/helena/env/daml/typescript-sdk/.generated/localnet-tls/ca.crt:/app/localnet-tls/ca.crt:ro"
448
+ command:
449
+ - pipeline
450
+ - ledger
451
+ - postgres-document
452
+ depends_on:
453
+ canton:
454
+ condition: service_healthy
455
+ splice-onboarding:
456
+ condition: service_healthy
457
+ postgres-pqs-extra-3:
458
+ condition: service_healthy
459
+ restart: on-failure:100
@@ -28,3 +28,61 @@ EXTRA_PQS_1_POSTGRES_NAME=postgres-pqs-extra-1
28
28
  EXTRA_PQS_1_POSTGRES_DB=pqs-extra-1
29
29
  EXTRA_PQS_1_POSTGRES_PUBLISHED_PORT=5541
30
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
@@ -153,14 +153,18 @@ prepare_tls_runtime_files() {
153
153
  [[ -n "${LOCALNET_TLS_CA_CERT_PATH:-}" ]] && ((supplied_count += 1))
154
154
 
155
155
  mkdir -p "$runtime_dir"
156
+ chmod 700 "$runtime_dir"
156
157
  if (( supplied_count > 0 )); then
157
158
  if (( supplied_count != 3 )); then
158
159
  echo "LOCALNET_TLS_CERT_CHAIN_PATH, LOCALNET_TLS_PRIVATE_KEY_PATH, and LOCALNET_TLS_CA_CERT_PATH must be set together." >&2
159
160
  return 1
160
161
  fi
161
- server_certificate_path="$LOCALNET_TLS_CERT_CHAIN_PATH"
162
- server_key_path="$LOCALNET_TLS_PRIVATE_KEY_PATH"
163
- ca_certificate_path="$LOCALNET_TLS_CA_CERT_PATH"
162
+ local supplied_server_certificate_path="$LOCALNET_TLS_CERT_CHAIN_PATH"
163
+ local supplied_server_key_path="$LOCALNET_TLS_PRIVATE_KEY_PATH"
164
+ local supplied_ca_certificate_path="$LOCALNET_TLS_CA_CERT_PATH"
165
+ server_certificate_path="$supplied_server_certificate_path"
166
+ server_key_path="$supplied_server_key_path"
167
+ ca_certificate_path="$supplied_ca_certificate_path"
164
168
  if [[ ! -r "$server_certificate_path" || ! -r "$server_key_path" || ! -r "$ca_certificate_path" ]]; then
165
169
  echo "Supplied TLS certificate, private key, or CA certificate is not readable." >&2
166
170
  return 1
@@ -179,6 +183,19 @@ prepare_tls_runtime_files() {
179
183
  echo "Supplied TLS private key does not match the server certificate." >&2
180
184
  return 1
181
185
  fi
186
+ if [[ "$supplied_server_certificate_path" != "$runtime_dir/server.crt" ]]; then
187
+ cp "$supplied_server_certificate_path" "$runtime_dir/server.crt"
188
+ fi
189
+ if [[ "$supplied_server_key_path" != "$runtime_dir/server.key" ]]; then
190
+ cp "$supplied_server_key_path" "$runtime_dir/server.key"
191
+ fi
192
+ if [[ "$supplied_ca_certificate_path" != "$runtime_dir/ca.crt" ]]; then
193
+ cp "$supplied_ca_certificate_path" "$runtime_dir/ca.crt"
194
+ fi
195
+ chmod 644 "$runtime_dir/server.crt" "$runtime_dir/server.key" "$runtime_dir/ca.crt"
196
+ server_certificate_path="$runtime_dir/server.crt"
197
+ server_key_path="$runtime_dir/server.key"
198
+ ca_certificate_path="$runtime_dir/ca.crt"
182
199
  else
183
200
  if [[ "$(resolve_tls_rotate)" == "1" ]]; then
184
201
  rm -f "$ca_key_path" "$ca_certificate_path" "$server_key_path" "$server_certificate_path"
@@ -214,6 +231,7 @@ EOF
214
231
  -out "$server_certificate_path" -extfile "$extensions_path" -extensions server_ext >/dev/null 2>&1
215
232
  rm -f "$csr_path" "$extensions_path" "$ca_certificate_path.srl"
216
233
  fi
234
+ chmod 644 "$server_key_path" "$server_certificate_path" "$ca_certificate_path"
217
235
  if ! openssl x509 -in "$server_certificate_path" -noout >/dev/null 2>&1 \
218
236
  || ! openssl pkey -in "$server_key_path" -noout >/dev/null 2>&1 \
219
237
  || ! openssl x509 -in "$ca_certificate_path" -noout >/dev/null 2>&1; then
@@ -272,15 +290,8 @@ services:
272
290
  volumes:
273
291
  - "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
274
292
  environment:
275
- - |
276
- ADDITIONAL_CONFIG_LOCALNET_TLS=
277
- splice-onboarding:
278
- volumes:
279
- - "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
280
- - "$onboarding_utils_file:/app/utils.sh:ro"
281
- environment:
282
- - LOCALNET_HTTP_SCHEME=https
283
- - CURL_CA_BUNDLE=/app/localnet-tls/ca.crt
293
+ ADDITIONAL_CONFIG_LOCALNET_TLS: |
294
+ # Trust the localnet CA for Splice's Canton clients.
284
295
  EOF
285
296
  for participant in app-provider app-user sv; do
286
297
  case "$participant" in
@@ -293,29 +304,36 @@ EOF
293
304
  fi
294
305
  if [[ "$participant" == "sv" ]]; then
295
306
  cat >> "$compose_file" <<'EOF'
296
- canton.validator-apps.sv-validator_backend.participant-client {
297
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
298
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
299
- }
300
- canton.scan-apps.scan-app.participant-client {
301
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
302
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
303
- }
304
- canton.sv-apps.sv.participant-client {
305
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
306
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
307
- }
307
+ canton.validator-apps.sv-validator_backend.participant-client {
308
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
309
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
310
+ }
311
+ canton.scan-apps.scan-app.participant-client {
312
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
313
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
314
+ }
315
+ canton.sv-apps.sv.participant-client {
316
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
317
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
318
+ }
308
319
  EOF
309
320
  else
310
321
  cat >> "$compose_file" <<EOF
311
- canton.validator-apps.${participant}-validator_backend.participant-client {
312
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
313
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
314
- }
322
+ canton.validator-apps.${participant}-validator_backend.participant-client {
323
+ admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
324
+ ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
325
+ }
315
326
  EOF
316
327
  fi
317
328
  done
318
329
  cat >> "$compose_file" <<EOF
330
+ splice-onboarding:
331
+ volumes:
332
+ - "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
333
+ - "$onboarding_utils_file:/app/utils.sh:ro"
334
+ environment:
335
+ - LOCALNET_HTTP_SCHEME=https
336
+ - CURL_CA_BUNDLE=/app/localnet-tls/ca.crt
319
337
  pqs-app-provider:
320
338
  environment:
321
339
  SCRIBE_SOURCE_LEDGER_TLS_CAFILE: /app/localnet-tls/ca.crt
@@ -912,7 +930,24 @@ prerequisite_services() {
912
930
  }
913
931
 
914
932
  dependent_services() {
915
- printf '%s\n' splice splice-onboarding pqs-app-provider pqs-sv
933
+ printf '%s\n' pqs-app-provider pqs-sv
934
+ }
935
+
936
+ start_splice_services() {
937
+ local -n compose_args_ref="$1"
938
+ local onboarding_container
939
+
940
+ # Start the combined Splice process without waiting for its own healthcheck.
941
+ # Compose still applies splice-onboarding's service_healthy dependency even
942
+ # with --no-deps when both services are passed to the same `up` invocation.
943
+ docker_compose "${compose_args_ref[@]}" up -d --no-recreate --no-deps splice
944
+ docker_compose "${compose_args_ref[@]}" create splice-onboarding
945
+ onboarding_container="$(docker_compose "${compose_args_ref[@]}" ps -a -q splice-onboarding | tail -n 1)"
946
+ if [[ -z "$onboarding_container" ]]; then
947
+ echo "Unable to resolve the splice-onboarding container." >&2
948
+ return 1
949
+ fi
950
+ docker start "$onboarding_container" >/dev/null
916
951
  }
917
952
 
918
953
  extra_pqs_services() {
@@ -1147,6 +1182,11 @@ start_ledger_stack() {
1147
1182
  docker_compose "${compose_args[@]}" up -d --no-recreate "${startup_services[@]}"
1148
1183
  wait_for_canton_health "$extra_participants"
1149
1184
 
1185
+ # SV initialization waits for onboarding contracts, while splice health waits
1186
+ # for SV and scan initialization. Start onboarding without Compose dependency
1187
+ # gating so its healthcheck can retry until those apps are ready; PQS still
1188
+ # starts afterward and retains its onboarding health dependency.
1189
+ start_splice_services compose_args
1150
1190
  docker_compose "${compose_args[@]}" up -d --no-recreate "${followup_services[@]}"
1151
1191
 
1152
1192
  if (( extra_participants > 0 )); then
@@ -89,7 +89,13 @@ EOF
89
89
  : > "$quickstart_dir/docker/modules/localnet/env/common.env"
90
90
  : > "$quickstart_dir/docker/modules/pqs/compose.yaml"
91
91
  : > "$quickstart_dir/docker/modules/pqs/compose.env"
92
- : > "$quickstart_dir/docker/modules/splice-onboarding/compose.yaml"
92
+ cat > "$quickstart_dir/docker/modules/splice-onboarding/compose.yaml" <<'EOF'
93
+ services:
94
+ splice-onboarding:
95
+ depends_on:
96
+ splice:
97
+ condition: service_healthy
98
+ EOF
93
99
  printf '%s\n' \
94
100
  'curl_check "http://$participant/v2/users"' \
95
101
  'curl_check "http://$validator/api/validator/v0/scan-proxy/dso-party-id"' \
@@ -161,7 +167,20 @@ printf 'stub docker %s\n' "$*"
161
167
  if [[ "${1:-}" == "compose" && "$*" == *" up -d --no-recreate postgres canton"* ]]; then
162
168
  exit 0
163
169
  fi
164
- if [[ "$*" == *" up -d --no-recreate splice splice-onboarding pqs-app-provider pqs-sv"* ]]; then
170
+ if [[ "$*" == *" up -d --no-recreate --no-deps splice"* ]]; then
171
+ exit 0
172
+ fi
173
+ if [[ "$*" == *" create splice-onboarding"* ]]; then
174
+ exit 0
175
+ fi
176
+ if [[ "$*" == *" ps -a -q splice-onboarding"* ]]; then
177
+ printf 'splice-onboarding\n'
178
+ exit 0
179
+ fi
180
+ if [[ "${1:-}" == "start" && "${2:-}" == "splice-onboarding" ]]; then
181
+ exit 0
182
+ fi
183
+ if [[ "$*" == *" up -d --no-recreate pqs-app-provider pqs-sv"* ]]; then
165
184
  exit 0
166
185
  fi
167
186
  exit 1
@@ -203,6 +222,7 @@ EOF
203
222
  START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
204
223
  LOCALNET_ES256_JWT="$es256_enabled" \
205
224
  LOCALNET_TLS="$tls_enabled" \
225
+ LOCALNET_TLS_ROTATE=1 \
206
226
  LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
207
227
  LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
208
228
  LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
@@ -216,6 +236,7 @@ EOF
216
236
  START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
217
237
  LOCALNET_ES256_JWT="$es256_enabled" \
218
238
  LOCALNET_TLS="$tls_enabled" \
239
+ LOCALNET_TLS_ROTATE=1 \
219
240
  LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
220
241
  LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
221
242
  LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
@@ -373,7 +394,6 @@ run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$t
373
394
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv up -d --no-recreate postgres canton'
374
395
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/quickstart/docker/modules/keycloak/compose.yaml --env-file '"$tmpdir"'/quickstart/docker/modules/keycloak/compose.env --profile keycloak down -v --remove-orphans' oauth2
375
396
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/quickstart/docker/modules/keycloak/compose.yaml --env-file '"$tmpdir"'/quickstart/docker/modules/keycloak/compose.env --profile keycloak up -d --no-recreate keycloak nginx-keycloak postgres canton' oauth2
376
- run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv up -d --no-recreate splice splice-onboarding pqs-app-provider pqs-sv' shared-secret staged-start
377
397
  run_case $'.PHONY: start\nstart:\n' 'stub docker-compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv down -v --remove-orphans' shared-secret compose-v1
378
398
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/generated/compose-extra-participants.yaml --env-file '"$tmpdir"'/generated/extra-participants.env down -v --remove-orphans' shared-secret default 3
379
399
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/generated/compose-extra-participants.yaml --env-file '"$tmpdir"'/generated/extra-participants.env up -d --no-recreate pqs-extra-1 pqs-extra-2 pqs-extra-3' shared-secret default 3
@@ -471,7 +491,7 @@ if grep -Fq 'canton.participants.app-user.ledger-api.tls {' "$tmpdir/tls/canton-
471
491
  fi
472
492
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/server.key:ro'
473
493
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/ca.crt:ro'
474
- assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'ADDITIONAL_CONFIG_LOCALNET_TLS='
494
+ assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'ADDITIONAL_CONFIG_LOCALNET_TLS: |'
475
495
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'LOCALNET_HTTP_SCHEME=https'
476
496
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'CURL_CA_BUNDLE=/app/localnet-tls/ca.crt'
477
497
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" "$tmpdir/tls/splice-onboarding-utils.sh:/app/utils.sh:ro"
@@ -484,7 +504,7 @@ if grep -Fq 'canton.validator-apps.app-user-validator_backend.participant-client
484
504
  echo "unexpected client TLS configuration for inactive app-user participant" >&2
485
505
  exit 1
486
506
  fi
487
- assert_file_mode "$tmpdir/tls/server.key" 600
507
+ assert_file_mode "$tmpdir/tls/server.key" 644
488
508
  assert_file_mode "$tmpdir/tls/ca.key" 600
489
509
  if ! openssl x509 -in "$tmpdir/tls/server.crt" -text -noout \
490
510
  | grep -Fq 'IP Address:127.0.0.1, IP Address:0.0.0.0'; then
@@ -523,11 +543,12 @@ openssl x509 -req -sha256 -days 3650 \
523
543
  -out "$tmpdir/supplied/server.crt" \
524
544
  -extfile "$tmpdir/supplied/server-extensions.cnf" -extensions server_ext >/dev/null 2>&1
525
545
  run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/tls/compose-localnet.yaml down -v --remove-orphans' shared-secret default 0 '' '' 0 1 "$tmpdir/supplied/server.crt" "$tmpdir/supplied/server.key" "$tmpdir/supplied/ca.crt"
526
- if [[ -e "$tmpdir/tls/server.key" || -e "$tmpdir/tls/ca.key" ]]; then
527
- echo 'supplied TLS mode unexpectedly generated private material' >&2
546
+ if [[ ! -e "$tmpdir/tls/server.key" || -e "$tmpdir/tls/ca.key" ]]; then
547
+ echo 'supplied TLS mode did not stage the container-readable key correctly' >&2
528
548
  exit 1
529
549
  fi
530
- assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" "$tmpdir/supplied/server.key:/app/localnet-tls/server.key:ro"
550
+ assert_file_mode "$tmpdir/tls/server.key" 644
551
+ assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" "$tmpdir/tls/server.key:/app/localnet-tls/server.key:ro"
531
552
  openssl genrsa -out "$tmpdir/supplied/mismatch.key" 2048 >/dev/null 2>&1
532
553
  run_case $'.PHONY: start\nstart:\n' 'Supplied TLS private key does not match the server certificate.' shared-secret default 0 '' '' 0 1 "$tmpdir/supplied/server.crt" "$tmpdir/supplied/mismatch.key" "$tmpdir/supplied/ca.crt" 1
533
554
  run_case $'.PHONY: start\nstart:\n' 'LOCALNET_TLS_CERT_CHAIN_PATH, LOCALNET_TLS_PRIVATE_KEY_PATH, and LOCALNET_TLS_CA_CERT_PATH must be set together.' shared-secret default 0 '' '' 0 1 "$tmpdir/supplied/server.crt" '' '' 1
@@ -536,4 +557,24 @@ run_case $'.PHONY: start\nstart:\n' 'ES256 bearer token written to '"$tmpdir"'/e
536
557
  assert_file_contains_text "$tmpdir/es256/canton-es256.conf" 'include file("/app/localnet-tls.conf")'
537
558
  assert_file_contains_text "$tmpdir/es256/compose-es256.yaml" '/app/es256-certificate.pem:ro'
538
559
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/server.crt:ro'
560
+ run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/localnet/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/splice-onboarding/compose.yaml -f '"$tmpdir"'/quickstart/docker/modules/pqs/compose.yaml --env-file .env --env-file .env.local --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/compose.env --env-file '"$tmpdir"'/quickstart/docker/modules/localnet/env/common.env --env-file '"$tmpdir"'/quickstart/docker/modules/pqs/compose.env --profile app-provider --profile pqs-app-provider --profile pqs-sv -f '"$tmpdir"'/generated/compose-extra-participants.yaml --env-file '"$tmpdir"'/generated/extra-participants.env -f '"$tmpdir"'/tls/compose-localnet.yaml -f '"$tmpdir"'/es256/compose-es256.yaml up -d --no-recreate --no-deps splice' shared-secret default 3 '' '' 1 1
561
+ exact_compose_config="$tmpdir/exact-compose.config"
562
+ if [[ -n "$real_docker" ]] && "$real_docker" compose version >/dev/null 2>&1; then
563
+ if ! "$real_docker" compose \
564
+ -f "$tmpdir/quickstart/compose.yaml" \
565
+ -f "$tmpdir/quickstart/docker/modules/localnet/compose.yaml" \
566
+ -f "$tmpdir/quickstart/docker/modules/splice-onboarding/compose.yaml" \
567
+ -f "$tmpdir/quickstart/docker/modules/pqs/compose.yaml" \
568
+ -f "$tmpdir/generated/compose-extra-participants.yaml" \
569
+ -f "$tmpdir/tls/compose-localnet.yaml" \
570
+ -f "$tmpdir/es256/compose-es256.yaml" \
571
+ --env-file "$tmpdir/quickstart/.env" \
572
+ --env-file "$tmpdir/quickstart/.env.local" \
573
+ --env-file "$tmpdir/generated/extra-participants.env" \
574
+ config > "$exact_compose_config" 2>&1; then
575
+ echo 'three extra participants plus TLS and ES256 did not produce valid merged Compose configuration' >&2
576
+ cat "$exact_compose_config" >&2
577
+ exit 1
578
+ fi
579
+ fi
539
580
  run_repo_root_env_case
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distrohelena/canton-typescript-sdk",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",