@distrohelena/canton-typescript-sdk 0.1.21 → 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"
@@ -190,6 +207,11 @@ prepare_tls_runtime_files() {
190
207
  openssl req -x509 -new -sha256 -days 3650 -key "$ca_key_path" \
191
208
  -subj "/CN=localnet-tls-ca" -out "$ca_certificate_path" >/dev/null 2>&1
192
209
  fi
210
+ if [[ -e "$server_certificate_path" ]] \
211
+ && ! openssl x509 -in "$server_certificate_path" -noout -ext subjectAltName 2>/dev/null \
212
+ | grep -Fq 'IP Address:127.0.0.1, IP Address:0.0.0.0'; then
213
+ rm -f "$server_key_path" "$server_certificate_path"
214
+ fi
193
215
  if [[ ! -e "$server_key_path" || ! -e "$server_certificate_path" ]]; then
194
216
  rm -f "$server_key_path" "$server_certificate_path"
195
217
  local csr_path="$runtime_dir/server.csr"
@@ -202,13 +224,14 @@ prepare_tls_runtime_files() {
202
224
  basicConstraints = CA:FALSE
203
225
  keyUsage = digitalSignature, keyEncipherment
204
226
  extendedKeyUsage = serverAuth
205
- subjectAltName = DNS:localhost, DNS:canton, IP:127.0.0.1
227
+ subjectAltName = DNS:localhost, DNS:canton, IP:127.0.0.1, IP:0.0.0.0
206
228
  EOF
207
229
  openssl x509 -req -sha256 -days 3650 -in "$csr_path" \
208
230
  -CA "$ca_certificate_path" -CAkey "$ca_key_path" -CAcreateserial \
209
231
  -out "$server_certificate_path" -extfile "$extensions_path" -extensions server_ext >/dev/null 2>&1
210
232
  rm -f "$csr_path" "$extensions_path" "$ca_certificate_path.srl"
211
233
  fi
234
+ chmod 644 "$server_key_path" "$server_certificate_path" "$ca_certificate_path"
212
235
  if ! openssl x509 -in "$server_certificate_path" -noout >/dev/null 2>&1 \
213
236
  || ! openssl pkey -in "$server_key_path" -noout >/dev/null 2>&1 \
214
237
  || ! openssl x509 -in "$ca_certificate_path" -noout >/dev/null 2>&1; then
@@ -267,15 +290,8 @@ services:
267
290
  volumes:
268
291
  - "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
269
292
  environment:
270
- - |
271
- ADDITIONAL_CONFIG_LOCALNET_TLS=
272
- splice-onboarding:
273
- volumes:
274
- - "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
275
- - "$onboarding_utils_file:/app/utils.sh:ro"
276
- environment:
277
- - LOCALNET_HTTP_SCHEME=https
278
- - CURL_CA_BUNDLE=/app/localnet-tls/ca.crt
293
+ ADDITIONAL_CONFIG_LOCALNET_TLS: |
294
+ # Trust the localnet CA for Splice's Canton clients.
279
295
  EOF
280
296
  for participant in app-provider app-user sv; do
281
297
  case "$participant" in
@@ -288,29 +304,36 @@ EOF
288
304
  fi
289
305
  if [[ "$participant" == "sv" ]]; then
290
306
  cat >> "$compose_file" <<'EOF'
291
- canton.validator-apps.sv-validator_backend.participant-client {
292
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
293
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
294
- }
295
- canton.scan-apps.scan-app.participant-client {
296
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
297
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
298
- }
299
- canton.sv-apps.sv.participant-client {
300
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
301
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
302
- }
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
+ }
303
319
  EOF
304
320
  else
305
321
  cat >> "$compose_file" <<EOF
306
- canton.validator-apps.${participant}-validator_backend.participant-client {
307
- admin-api.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
308
- ledger-api.client-config.tls.trust-collection-file = "/app/localnet-tls/ca.crt"
309
- }
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
+ }
310
326
  EOF
311
327
  fi
312
328
  done
313
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
314
337
  pqs-app-provider:
315
338
  environment:
316
339
  SCRIBE_SOURCE_LEDGER_TLS_CAFILE: /app/localnet-tls/ca.crt
@@ -839,7 +862,7 @@ EOF
839
862
  if [[ "$(resolve_tls_enabled)" == "1" ]]; then
840
863
  printf ' - "%s:/app/localnet-tls/ca.crt:ro"\n' "${LOCALNET_TLS_CA_CERT_PATH}"
841
864
  fi
842
- cat <<'EOF'
865
+ cat <<EOF
843
866
  command:
844
867
  - pipeline
845
868
  - ledger
@@ -907,7 +930,24 @@ prerequisite_services() {
907
930
  }
908
931
 
909
932
  dependent_services() {
910
- 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
911
951
  }
912
952
 
913
953
  extra_pqs_services() {
@@ -1142,6 +1182,11 @@ start_ledger_stack() {
1142
1182
  docker_compose "${compose_args[@]}" up -d --no-recreate "${startup_services[@]}"
1143
1183
  wait_for_canton_health "$extra_participants"
1144
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
1145
1190
  docker_compose "${compose_args[@]}" up -d --no-recreate "${followup_services[@]}"
1146
1191
 
1147
1192
  if (( extra_participants > 0 )); then
@@ -6,6 +6,7 @@ SCRIPT_DIR="$REPO_ROOT/node"
6
6
  REPO_ENV_FILE="$REPO_ROOT/.env"
7
7
 
8
8
  tmpdir="$(mktemp -d)"
9
+ real_docker="$(command -v docker || true)"
9
10
  root_env_backup="$tmpdir/root-env.backup"
10
11
  root_env_exists=0
11
12
  if [[ -f "$REPO_ENV_FILE" ]]; then
@@ -53,15 +54,48 @@ run_case() {
53
54
  "$generated_dir"
54
55
  ln -s "$quickstart_dir" "$quickstart_root_dir/quickstart"
55
56
  printf '%s\n' "$makefile_targets" > "$quickstart_dir/Makefile"
56
- printf 'DOCKER_NETWORK=quickstart\nSPLICE_VERSION=0.6.5\n' > "$quickstart_dir/.env"
57
+ printf '%s\n' \
58
+ 'DOCKER_NETWORK=quickstart' \
59
+ 'SPLICE_VERSION=0.6.5' \
60
+ 'SCRIBE_IMAGE=scribe' \
61
+ 'SCRIBE_VERSION=test' \
62
+ 'POSTGRES_VERSION=16' \
63
+ 'DB_USER=test' \
64
+ 'DB_PASSWORD=test' \
65
+ > "$quickstart_dir/.env"
66
+ cat > "$quickstart_dir/compose.yaml" <<'EOF'
67
+ volumes:
68
+ onboarding:
69
+
70
+ services:
71
+ postgres:
72
+ image: postgres:16
73
+ canton:
74
+ image: canton:test
75
+ splice:
76
+ image: splice:test
77
+ splice-onboarding:
78
+ image: onboarding:test
79
+ pqs-app-provider:
80
+ image: pqs:test
81
+ pqs-app-user:
82
+ image: pqs:test
83
+ pqs-sv:
84
+ image: pqs:test
85
+ EOF
57
86
  printf 'AUTH_MODE=%s\n' "$auth_mode" > "$quickstart_dir/.env.local"
58
- : > "$quickstart_dir/compose.yaml"
59
87
  : > "$quickstart_dir/docker/modules/localnet/compose.yaml"
60
88
  : > "$quickstart_dir/docker/modules/localnet/compose.env"
61
89
  : > "$quickstart_dir/docker/modules/localnet/env/common.env"
62
90
  : > "$quickstart_dir/docker/modules/pqs/compose.yaml"
63
91
  : > "$quickstart_dir/docker/modules/pqs/compose.env"
64
- : > "$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
65
99
  printf '%s\n' \
66
100
  'curl_check "http://$participant/v2/users"' \
67
101
  'curl_check "http://$validator/api/validator/v0/scan-proxy/dso-party-id"' \
@@ -133,7 +167,20 @@ printf 'stub docker %s\n' "$*"
133
167
  if [[ "${1:-}" == "compose" && "$*" == *" up -d --no-recreate postgres canton"* ]]; then
134
168
  exit 0
135
169
  fi
136
- 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
137
184
  exit 0
138
185
  fi
139
186
  exit 1
@@ -175,6 +222,7 @@ EOF
175
222
  START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
176
223
  LOCALNET_ES256_JWT="$es256_enabled" \
177
224
  LOCALNET_TLS="$tls_enabled" \
225
+ LOCALNET_TLS_ROTATE=1 \
178
226
  LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
179
227
  LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
180
228
  LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
@@ -188,6 +236,7 @@ EOF
188
236
  START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
189
237
  LOCALNET_ES256_JWT="$es256_enabled" \
190
238
  LOCALNET_TLS="$tls_enabled" \
239
+ LOCALNET_TLS_ROTATE=1 \
191
240
  LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
192
241
  LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
193
242
  LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
@@ -345,7 +394,6 @@ run_case $'.PHONY: start\nstart:\n' 'stub docker compose -f compose.yaml -f '"$t
345
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'
346
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
347
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
348
- 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
349
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
350
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
351
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
@@ -408,6 +456,30 @@ assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf"
408
456
  assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" ' validator-party-hint = "${EXTRA_VALIDATOR_1_PARTY_HINT}"'
409
457
  assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" ' domains.global.buy-extra-traffic {'
410
458
  assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" 'canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}" }'
459
+ run_case $'.PHONY: start\nstart:\n' 'stub env AUTH_MODE=shared-secret' shared-secret default 2 '' '' 0 1
460
+ assert_file_contains_text "$tmpdir/generated/additional-config.extra-participants.conf" 'canton.participants.extra-1.ledger-api.tls {'
461
+ assert_file_contains_text "$tmpdir/generated/additional-config.extra-validators.conf" 'canton.validator-apps.extra-1-validator_backend.participant-client {'
462
+ compose_config="$tmpdir/extra-tls-compose.config"
463
+ if [[ -n "$real_docker" ]] && "$real_docker" compose version >/dev/null 2>&1; then
464
+ if ! "$real_docker" compose \
465
+ -f "$tmpdir/quickstart/compose.yaml" \
466
+ -f "$tmpdir/quickstart/docker/modules/localnet/compose.yaml" \
467
+ -f "$tmpdir/quickstart/docker/modules/splice-onboarding/compose.yaml" \
468
+ -f "$tmpdir/quickstart/docker/modules/pqs/compose.yaml" \
469
+ -f "$tmpdir/generated/compose-extra-participants.yaml" \
470
+ -f "$tmpdir/tls/compose-localnet.yaml" \
471
+ --env-file "$tmpdir/quickstart/.env" \
472
+ --env-file "$tmpdir/quickstart/.env.local" \
473
+ --env-file "$tmpdir/generated/extra-participants.env" \
474
+ config > "$compose_config" 2>&1; then
475
+ echo 'extra participants plus TLS did not produce valid merged Compose configuration' >&2
476
+ cat "$compose_config" >&2
477
+ exit 1
478
+ fi
479
+ else
480
+ assert_file_contains_text "$tmpdir/generated/compose-extra-participants.yaml" ' postgres-pqs-extra-1:'
481
+ assert_file_contains_text "$tmpdir/generated/compose-extra-participants.yaml" ' postgres-pqs-extra-1:'
482
+ fi
411
483
  run_case $'.PHONY: start-local-ledger\nstart-local-ledger:\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
412
484
  assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.app-provider.ledger-api.tls {'
413
485
  assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.app-provider.admin-api.tls {'
@@ -419,7 +491,7 @@ if grep -Fq 'canton.participants.app-user.ledger-api.tls {' "$tmpdir/tls/canton-
419
491
  fi
420
492
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/server.key:ro'
421
493
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/ca.crt:ro'
422
- 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: |'
423
495
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'LOCALNET_HTTP_SCHEME=https'
424
496
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" 'CURL_CA_BUNDLE=/app/localnet-tls/ca.crt'
425
497
  assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" "$tmpdir/tls/splice-onboarding-utils.sh:/app/utils.sh:ro"
@@ -432,8 +504,14 @@ if grep -Fq 'canton.validator-apps.app-user-validator_backend.participant-client
432
504
  echo "unexpected client TLS configuration for inactive app-user participant" >&2
433
505
  exit 1
434
506
  fi
435
- assert_file_mode "$tmpdir/tls/server.key" 600
507
+ assert_file_mode "$tmpdir/tls/server.key" 644
436
508
  assert_file_mode "$tmpdir/tls/ca.key" 600
509
+ if ! openssl x509 -in "$tmpdir/tls/server.crt" -text -noout \
510
+ | grep -Fq 'IP Address:127.0.0.1, IP Address:0.0.0.0'; then
511
+ echo 'generated TLS certificate is missing the 0.0.0.0 subject alternative name' >&2
512
+ openssl x509 -in "$tmpdir/tls/server.crt" -text -noout >&2
513
+ exit 1
514
+ fi
437
515
  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 down -v --remove-orphans' shared-secret default 2 '' '' 0 1
438
516
  assert_file_contains_text "$tmpdir/generated/additional-config.extra-participants.conf" 'canton.participants.extra-1.ledger-api.tls {'
439
517
  assert_file_contains_text "$tmpdir/generated/additional-config.extra-participants.conf" 'canton.participants.extra-2.admin-api.tls {'
@@ -465,11 +543,12 @@ openssl x509 -req -sha256 -days 3650 \
465
543
  -out "$tmpdir/supplied/server.crt" \
466
544
  -extfile "$tmpdir/supplied/server-extensions.cnf" -extensions server_ext >/dev/null 2>&1
467
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"
468
- if [[ -e "$tmpdir/tls/server.key" || -e "$tmpdir/tls/ca.key" ]]; then
469
- 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
470
548
  exit 1
471
549
  fi
472
- 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"
473
552
  openssl genrsa -out "$tmpdir/supplied/mismatch.key" 2048 >/dev/null 2>&1
474
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
475
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
@@ -478,4 +557,24 @@ run_case $'.PHONY: start\nstart:\n' 'ES256 bearer token written to '"$tmpdir"'/e
478
557
  assert_file_contains_text "$tmpdir/es256/canton-es256.conf" 'include file("/app/localnet-tls.conf")'
479
558
  assert_file_contains_text "$tmpdir/es256/compose-es256.yaml" '/app/es256-certificate.pem:ro'
480
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
481
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.21",
3
+ "version": "0.1.24",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",