@distrohelena/canton-typescript-sdk 0.1.17 → 0.1.18
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 +43 -0
- package/dist/client/canton-client-options.d.ts +2 -0
- package/dist/client/canton-client-options.js +2 -0
- package/dist/transports/grpc/grpc-call-options-factory.d.ts +1 -1
- package/dist/transports/grpc/grpc-call-options-factory.js +8 -4
- package/dist/transports/grpc/grpc-channel-factory.js +1 -1
- package/node/start-local.sh +197 -2
- package/node/stop-local.sh +25 -1
- package/node/test-start-local.sh +101 -4
- package/node/test-stop-local.sh +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -127,6 +127,49 @@ already be a Ledger API user with the appropriate rights on each participant.
|
|
|
127
127
|
Extra participants use the existing shared-secret onboarding flow; the current
|
|
128
128
|
OAuth2-plus-extras limitation still applies.
|
|
129
129
|
|
|
130
|
+
### Optional localnet TLS
|
|
131
|
+
|
|
132
|
+
Set `LOCALNET_TLS=1` to enable TLS on every participant Ledger API and Admin API
|
|
133
|
+
listener, including generated extra participants. TLS is disabled by default,
|
|
134
|
+
so `LOCALNET_TLS=0` preserves the existing Quickstart behavior. The launcher
|
|
135
|
+
uses direct Compose mode when TLS is enabled so it can apply the generated
|
|
136
|
+
configuration overlay.
|
|
137
|
+
|
|
138
|
+
By default, development-only material is generated in
|
|
139
|
+
`.generated/localnet-tls`: `ca.crt`, `server.crt`, and `server.key`. Set
|
|
140
|
+
`LOCALNET_TLS_ROTATE=1` to replace it. To provide your own material, set all
|
|
141
|
+
three variables together:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
LOCALNET_TLS=1 \
|
|
145
|
+
LOCALNET_TLS_CERT_CHAIN_PATH=/path/to/server-chain.pem \
|
|
146
|
+
LOCALNET_TLS_PRIVATE_KEY_PATH=/path/to/server-key.pem \
|
|
147
|
+
LOCALNET_TLS_CA_CERT_PATH=/path/to/root-ca.pem \
|
|
148
|
+
canton-localnet-start
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The server certificate must cover the hostname used by the client, normally
|
|
152
|
+
`localhost` for host-side SDK calls. Client certificate authentication is not
|
|
153
|
+
enabled; authentication remains controlled by the existing Quickstart
|
|
154
|
+
`AUTH_MODE` and optional ES256 settings.
|
|
155
|
+
|
|
156
|
+
The SDK gRPC channels remain TLS by default. For generated localnet material,
|
|
157
|
+
pass the generated CA to the client:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { readFileSync } from "node:fs";
|
|
161
|
+
|
|
162
|
+
const client = new CantonClient(new CantonClientOptions({
|
|
163
|
+
transportKind: TransportKind.grpc,
|
|
164
|
+
ledgerEndpoint: "localhost:3901",
|
|
165
|
+
ledgerAdminEndpoint: "localhost:3902",
|
|
166
|
+
participantAdminEndpoint: "localhost:3902",
|
|
167
|
+
grpcTlsRootCertificates: readFileSync(
|
|
168
|
+
".generated/localnet-tls/ca.crt",
|
|
169
|
+
),
|
|
170
|
+
}));
|
|
171
|
+
```
|
|
172
|
+
|
|
130
173
|
The live suite runs single-worker with an extended timeout because it mutates and reads a shared localnet.
|
|
131
174
|
|
|
132
175
|
Prerequisites:
|
|
@@ -9,6 +9,7 @@ export declare class CantonClientOptions {
|
|
|
9
9
|
readonly ledgerAdminEndpoint?: string;
|
|
10
10
|
readonly participantAdminEndpoint?: string;
|
|
11
11
|
readonly grpcChannelSecurity: GrpcChannelSecurity;
|
|
12
|
+
readonly grpcTlsRootCertificates?: Uint8Array;
|
|
12
13
|
readonly ledgerGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
13
14
|
readonly ledgerAdminGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
14
15
|
readonly participantAdminGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
@@ -25,6 +26,7 @@ export declare class CantonClientOptions {
|
|
|
25
26
|
ledgerAdminEndpoint?: string;
|
|
26
27
|
participantAdminEndpoint?: string;
|
|
27
28
|
grpcChannelSecurity?: GrpcChannelSecurity;
|
|
29
|
+
grpcTlsRootCertificates?: Uint8Array;
|
|
28
30
|
ledgerGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
29
31
|
ledgerAdminGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
30
32
|
participantAdminGrpcChannelSecurity?: GrpcChannelSecurity;
|
|
@@ -5,6 +5,7 @@ export class CantonClientOptions {
|
|
|
5
5
|
ledgerAdminEndpoint;
|
|
6
6
|
participantAdminEndpoint;
|
|
7
7
|
grpcChannelSecurity;
|
|
8
|
+
grpcTlsRootCertificates;
|
|
8
9
|
ledgerGrpcChannelSecurity;
|
|
9
10
|
ledgerAdminGrpcChannelSecurity;
|
|
10
11
|
participantAdminGrpcChannelSecurity;
|
|
@@ -22,6 +23,7 @@ export class CantonClientOptions {
|
|
|
22
23
|
this.participantAdminEndpoint = init.participantAdminEndpoint;
|
|
23
24
|
this.grpcChannelSecurity =
|
|
24
25
|
init.grpcChannelSecurity ?? GrpcChannelSecurity.tls;
|
|
26
|
+
this.grpcTlsRootCertificates = init.grpcTlsRootCertificates;
|
|
25
27
|
this.ledgerGrpcChannelSecurity = init.ledgerGrpcChannelSecurity;
|
|
26
28
|
this.ledgerAdminGrpcChannelSecurity =
|
|
27
29
|
init.ledgerAdminGrpcChannelSecurity;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IAuthProvider } from "../../core/auth/auth-provider.interface.js";
|
|
2
2
|
import { RequestOptions } from "../../core/types/request-options.js";
|
|
3
3
|
import { GrpcChannelSecurity } from "../../core/types/grpc-channel-security.js";
|
|
4
|
-
export declare function createGrpcChannelCredentials(security: GrpcChannelSecurity): import("@grpc/grpc-js").ChannelCredentials;
|
|
4
|
+
export declare function createGrpcChannelCredentials(security: GrpcChannelSecurity, tlsRootCertificates?: Uint8Array): import("@grpc/grpc-js").ChannelCredentials;
|
|
5
5
|
export declare function buildGrpcCallOptionsAsync(authProvider?: IAuthProvider, defaultTimeoutMs?: number, options?: RequestOptions): Promise<{
|
|
6
6
|
meta: Record<string, string>;
|
|
7
7
|
timeout?: number;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { credentials } from "@grpc/grpc-js";
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
2
3
|
import { resolveRequestTimeoutMs } from "../../core/types/request-timeout.js";
|
|
3
4
|
import { GrpcChannelSecurity } from "../../core/types/grpc-channel-security.js";
|
|
4
|
-
export function createGrpcChannelCredentials(security) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export function createGrpcChannelCredentials(security, tlsRootCertificates) {
|
|
6
|
+
if (security === GrpcChannelSecurity.insecure) {
|
|
7
|
+
return credentials.createInsecure();
|
|
8
|
+
}
|
|
9
|
+
return tlsRootCertificates === undefined
|
|
10
|
+
? credentials.createSsl()
|
|
11
|
+
: credentials.createSsl(Buffer.from(tlsRootCertificates));
|
|
8
12
|
}
|
|
9
13
|
export async function buildGrpcCallOptionsAsync(authProvider, defaultTimeoutMs, options) {
|
|
10
14
|
const timeout = resolveRequestTimeoutMs(defaultTimeoutMs, options);
|
|
@@ -32,7 +32,7 @@ import { buildGrpcCallOptionsAsync, createGrpcChannelCredentials, } from "./grpc
|
|
|
32
32
|
export function createGrpcOperations(options, endpoint, grpcChannelSecurity, dependencies = {}) {
|
|
33
33
|
const rpcTransport = new ProtobufGrpcTransport({
|
|
34
34
|
host: normalizeGrpcHost(endpoint),
|
|
35
|
-
channelCredentials: createGrpcChannelCredentials(grpcChannelSecurity),
|
|
35
|
+
channelCredentials: createGrpcChannelCredentials(grpcChannelSecurity, options.grpcTlsRootCertificates),
|
|
36
36
|
clientOptions: options.grpcConnectTimeoutMs === undefined
|
|
37
37
|
? undefined
|
|
38
38
|
: {
|
package/node/start-local.sh
CHANGED
|
@@ -98,6 +98,167 @@ es256_runtime_dir() {
|
|
|
98
98
|
printf '%s\n' "${START_LOCAL_ES256_RUNTIME_DIR:-$REPO_ROOT/.generated/localnet-es256}"
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
resolve_tls_enabled() {
|
|
102
|
+
local value="${LOCALNET_TLS:-0}"
|
|
103
|
+
if [[ "$value" != "0" && "$value" != "1" ]]; then
|
|
104
|
+
echo "LOCALNET_TLS must be 0 or 1." >&2
|
|
105
|
+
return 1
|
|
106
|
+
fi
|
|
107
|
+
printf '%s\n' "$value"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
resolve_tls_rotate() {
|
|
111
|
+
local value="${LOCALNET_TLS_ROTATE:-0}"
|
|
112
|
+
if [[ "$value" != "0" && "$value" != "1" ]]; then
|
|
113
|
+
echo "LOCALNET_TLS_ROTATE must be 0 or 1." >&2
|
|
114
|
+
return 1
|
|
115
|
+
fi
|
|
116
|
+
printf '%s\n' "$value"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
tls_runtime_dir() {
|
|
120
|
+
printf '%s\n' "${START_LOCAL_TLS_RUNTIME_DIR:-$REPO_ROOT/.generated/localnet-tls}"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
prepare_tls_runtime_files() {
|
|
124
|
+
local enabled
|
|
125
|
+
enabled="$(resolve_tls_enabled)"
|
|
126
|
+
if [[ "$enabled" != "1" ]]; then
|
|
127
|
+
return 0
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
local runtime_dir
|
|
131
|
+
runtime_dir="$(tls_runtime_dir)"
|
|
132
|
+
local ca_key_path="$runtime_dir/ca.key"
|
|
133
|
+
local ca_certificate_path="$runtime_dir/ca.crt"
|
|
134
|
+
local server_key_path="$runtime_dir/server.key"
|
|
135
|
+
local server_certificate_path="$runtime_dir/server.crt"
|
|
136
|
+
local compose_file="$runtime_dir/compose-localnet.yaml"
|
|
137
|
+
local tls_fragment_file="$runtime_dir/canton-tls.conf"
|
|
138
|
+
local canton_config_file="$runtime_dir/canton-localnet.conf"
|
|
139
|
+
local supplied_count=0
|
|
140
|
+
|
|
141
|
+
[[ -n "${LOCALNET_TLS_CERT_CHAIN_PATH:-}" ]] && ((supplied_count += 1))
|
|
142
|
+
[[ -n "${LOCALNET_TLS_PRIVATE_KEY_PATH:-}" ]] && ((supplied_count += 1))
|
|
143
|
+
[[ -n "${LOCALNET_TLS_CA_CERT_PATH:-}" ]] && ((supplied_count += 1))
|
|
144
|
+
|
|
145
|
+
mkdir -p "$runtime_dir"
|
|
146
|
+
if (( supplied_count > 0 )); then
|
|
147
|
+
if (( supplied_count != 3 )); then
|
|
148
|
+
echo "LOCALNET_TLS_CERT_CHAIN_PATH, LOCALNET_TLS_PRIVATE_KEY_PATH, and LOCALNET_TLS_CA_CERT_PATH must be set together." >&2
|
|
149
|
+
return 1
|
|
150
|
+
fi
|
|
151
|
+
server_certificate_path="$LOCALNET_TLS_CERT_CHAIN_PATH"
|
|
152
|
+
server_key_path="$LOCALNET_TLS_PRIVATE_KEY_PATH"
|
|
153
|
+
ca_certificate_path="$LOCALNET_TLS_CA_CERT_PATH"
|
|
154
|
+
if [[ ! -r "$server_certificate_path" || ! -r "$server_key_path" || ! -r "$ca_certificate_path" ]]; then
|
|
155
|
+
echo "Supplied TLS certificate, private key, or CA certificate is not readable." >&2
|
|
156
|
+
return 1
|
|
157
|
+
fi
|
|
158
|
+
if ! openssl x509 -in "$server_certificate_path" -noout >/dev/null 2>&1 \
|
|
159
|
+
|| ! openssl pkey -in "$server_key_path" -noout >/dev/null 2>&1 \
|
|
160
|
+
|| ! openssl x509 -in "$ca_certificate_path" -noout >/dev/null 2>&1 \
|
|
161
|
+
|| ! openssl verify -CAfile "$ca_certificate_path" "$server_certificate_path" >/dev/null 2>&1; then
|
|
162
|
+
echo "Supplied TLS material is not valid PEM certificate/key material." >&2
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
local certificate_public_key private_public_key
|
|
166
|
+
if ! certificate_public_key="$(openssl x509 -in "$server_certificate_path" -pubkey -noout | openssl pkey -pubin -outform DER | sha256sum | awk '{print $1}')" \
|
|
167
|
+
|| ! private_public_key="$(openssl pkey -in "$server_key_path" -pubout | openssl pkey -pubin -outform DER | sha256sum | awk '{print $1}')" \
|
|
168
|
+
|| [[ "$certificate_public_key" != "$private_public_key" ]]; then
|
|
169
|
+
echo "Supplied TLS private key does not match the server certificate." >&2
|
|
170
|
+
return 1
|
|
171
|
+
fi
|
|
172
|
+
else
|
|
173
|
+
if [[ "$(resolve_tls_rotate)" == "1" ]]; then
|
|
174
|
+
rm -f "$ca_key_path" "$ca_certificate_path" "$server_key_path" "$server_certificate_path"
|
|
175
|
+
fi
|
|
176
|
+
if [[ ! -e "$ca_key_path" || ! -e "$ca_certificate_path" ]]; then
|
|
177
|
+
rm -f "$ca_key_path" "$ca_certificate_path"
|
|
178
|
+
openssl genrsa -out "$ca_key_path" 2048 >/dev/null 2>&1
|
|
179
|
+
chmod 600 "$ca_key_path"
|
|
180
|
+
openssl req -x509 -new -sha256 -days 3650 -key "$ca_key_path" \
|
|
181
|
+
-subj "/CN=localnet-tls-ca" -out "$ca_certificate_path" >/dev/null 2>&1
|
|
182
|
+
fi
|
|
183
|
+
if [[ ! -e "$server_key_path" || ! -e "$server_certificate_path" ]]; then
|
|
184
|
+
rm -f "$server_key_path" "$server_certificate_path"
|
|
185
|
+
local csr_path="$runtime_dir/server.csr"
|
|
186
|
+
local extensions_path="$runtime_dir/server-extensions.cnf"
|
|
187
|
+
openssl genrsa -out "$server_key_path" 2048 >/dev/null 2>&1
|
|
188
|
+
chmod 600 "$server_key_path"
|
|
189
|
+
openssl req -new -sha256 -key "$server_key_path" -subj "/CN=localhost" -out "$csr_path" >/dev/null 2>&1
|
|
190
|
+
cat > "$extensions_path" <<'EOF'
|
|
191
|
+
[server_ext]
|
|
192
|
+
basicConstraints = CA:FALSE
|
|
193
|
+
keyUsage = digitalSignature, keyEncipherment
|
|
194
|
+
extendedKeyUsage = serverAuth
|
|
195
|
+
subjectAltName = DNS:localhost, DNS:canton, IP:127.0.0.1
|
|
196
|
+
EOF
|
|
197
|
+
openssl x509 -req -sha256 -days 3650 -in "$csr_path" \
|
|
198
|
+
-CA "$ca_certificate_path" -CAkey "$ca_key_path" -CAcreateserial \
|
|
199
|
+
-out "$server_certificate_path" -extfile "$extensions_path" -extensions server_ext >/dev/null 2>&1
|
|
200
|
+
rm -f "$csr_path" "$extensions_path" "$ca_certificate_path.srl"
|
|
201
|
+
fi
|
|
202
|
+
if ! openssl x509 -in "$server_certificate_path" -noout >/dev/null 2>&1 \
|
|
203
|
+
|| ! openssl pkey -in "$server_key_path" -noout >/dev/null 2>&1 \
|
|
204
|
+
|| ! openssl x509 -in "$ca_certificate_path" -noout >/dev/null 2>&1; then
|
|
205
|
+
echo "Generated TLS material is invalid." >&2
|
|
206
|
+
return 1
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
cat > "$tls_fragment_file" <<'EOF'
|
|
211
|
+
canton.participants.app-provider.ledger-api.tls {
|
|
212
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
213
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
214
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
215
|
+
}
|
|
216
|
+
canton.participants.app-provider.admin-api.tls {
|
|
217
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
218
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
219
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
220
|
+
}
|
|
221
|
+
canton.participants.app-user.ledger-api.tls {
|
|
222
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
223
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
224
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
225
|
+
}
|
|
226
|
+
canton.participants.app-user.admin-api.tls {
|
|
227
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
228
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
229
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
230
|
+
}
|
|
231
|
+
canton.participants.sv.ledger-api.tls {
|
|
232
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
233
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
234
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
235
|
+
}
|
|
236
|
+
canton.participants.sv.admin-api.tls {
|
|
237
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
238
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
239
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
240
|
+
}
|
|
241
|
+
EOF
|
|
242
|
+
cat > "$canton_config_file" <<'EOF'
|
|
243
|
+
include file("/app/base-app.conf")
|
|
244
|
+
include file("/app/localnet-tls.conf")
|
|
245
|
+
EOF
|
|
246
|
+
cat > "$compose_file" <<EOF
|
|
247
|
+
services:
|
|
248
|
+
canton:
|
|
249
|
+
volumes:
|
|
250
|
+
- "${LOCALNET_DIR}/conf/canton/app.conf:/app/base-app.conf:ro"
|
|
251
|
+
- "$canton_config_file:/app/app.conf:ro"
|
|
252
|
+
- "$tls_fragment_file:/app/localnet-tls.conf:ro"
|
|
253
|
+
- "$server_certificate_path:/app/localnet-tls/server.crt:ro"
|
|
254
|
+
- "$server_key_path:/app/localnet-tls/server.key:ro"
|
|
255
|
+
- "$ca_certificate_path:/app/localnet-tls/ca.crt:ro"
|
|
256
|
+
EOF
|
|
257
|
+
export LOCALNET_TLS_COMPOSE_FILE="$compose_file"
|
|
258
|
+
export LOCALNET_TLS_FRAGMENT_FILE="$tls_fragment_file"
|
|
259
|
+
export LOCALNET_TLS_CA_CERT_PATH="$ca_certificate_path"
|
|
260
|
+
}
|
|
261
|
+
|
|
101
262
|
prepare_es256_runtime_files() {
|
|
102
263
|
local runtime_dir
|
|
103
264
|
runtime_dir="$(es256_runtime_dir)"
|
|
@@ -150,6 +311,8 @@ prepare_es256_runtime_files() {
|
|
|
150
311
|
cat > "$canton_config_file" <<EOF
|
|
151
312
|
include file("/app/base-app.conf")
|
|
152
313
|
|
|
314
|
+
$(if [[ "$(resolve_tls_enabled)" == "1" ]]; then printf 'include file("/app/localnet-tls.conf")\n'; fi)
|
|
315
|
+
|
|
153
316
|
EOF
|
|
154
317
|
local participant profile
|
|
155
318
|
for participant in app-provider app-user sv; do
|
|
@@ -195,6 +358,13 @@ append_es256_args() {
|
|
|
195
358
|
fi
|
|
196
359
|
}
|
|
197
360
|
|
|
361
|
+
append_tls_args() {
|
|
362
|
+
local -n compose_args_ref="$1"
|
|
363
|
+
if [[ "$(resolve_tls_enabled)" == "1" ]]; then
|
|
364
|
+
compose_args_ref+=( -f "$LOCALNET_TLS_COMPOSE_FILE" )
|
|
365
|
+
fi
|
|
366
|
+
}
|
|
367
|
+
|
|
198
368
|
resolve_docker_compose_cmd() {
|
|
199
369
|
if (( ${#DOCKER_COMPOSE_CMD[@]} > 0 )); then
|
|
200
370
|
return 0
|
|
@@ -414,6 +584,25 @@ canton.participants.extra-${index}.ledger-api.auth-services = [
|
|
|
414
584
|
}
|
|
415
585
|
]
|
|
416
586
|
|
|
587
|
+
EOF
|
|
588
|
+
done
|
|
589
|
+
fi
|
|
590
|
+
|
|
591
|
+
if [[ "$(resolve_tls_enabled)" == "1" ]]; then
|
|
592
|
+
local index
|
|
593
|
+
for ((index = 1; index <= count; index++)); do
|
|
594
|
+
cat >> "$canton_config_file" <<EOF
|
|
595
|
+
canton.participants.extra-${index}.ledger-api.tls {
|
|
596
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
597
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
598
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
599
|
+
}
|
|
600
|
+
canton.participants.extra-${index}.admin-api.tls {
|
|
601
|
+
cert-chain-file = "/app/localnet-tls/server.crt"
|
|
602
|
+
private-key-file = "/app/localnet-tls/server.key"
|
|
603
|
+
trust-collection-file = "/app/localnet-tls/ca.crt"
|
|
604
|
+
}
|
|
605
|
+
|
|
417
606
|
EOF
|
|
418
607
|
done
|
|
419
608
|
fi
|
|
@@ -808,6 +997,7 @@ start_ledger_stack() {
|
|
|
808
997
|
export SV_PROFILE=on
|
|
809
998
|
export PQS_SV_PROFILE=on
|
|
810
999
|
load_localnet_common_env "$localnet_dir/env/common.env"
|
|
1000
|
+
prepare_tls_runtime_files
|
|
811
1001
|
prepare_es256_runtime_files
|
|
812
1002
|
local extra_participants
|
|
813
1003
|
extra_participants="$(resolve_extra_participants)"
|
|
@@ -841,6 +1031,7 @@ start_ledger_stack() {
|
|
|
841
1031
|
fi
|
|
842
1032
|
|
|
843
1033
|
append_extra_participant_args "$extra_participants" "$auth_mode" compose_args
|
|
1034
|
+
append_tls_args compose_args
|
|
844
1035
|
append_es256_args compose_args
|
|
845
1036
|
docker_compose "${compose_args[@]}" down -v --remove-orphans
|
|
846
1037
|
mapfile -t startup_services < <(prerequisite_services "$auth_mode")
|
|
@@ -873,12 +1064,16 @@ if [[ ! -f .env.local ]]; then
|
|
|
873
1064
|
make setup
|
|
874
1065
|
fi
|
|
875
1066
|
|
|
876
|
-
if [[ "$(resolve_es256_enabled)" != "1" ]] && make_target_exists start-local-ledger; then
|
|
1067
|
+
if [[ "$(resolve_es256_enabled)" != "1" && "$(resolve_tls_enabled)" != "1" ]] && make_target_exists start-local-ledger; then
|
|
877
1068
|
make start-local-ledger
|
|
878
1069
|
else
|
|
879
1070
|
auth_mode="$(read_env_value AUTH_MODE || true)"
|
|
880
1071
|
auth_mode="${auth_mode:-shared-secret}"
|
|
881
|
-
|
|
1072
|
+
if [[ "$(resolve_es256_enabled)" == "1" || "$(resolve_tls_enabled)" == "1" ]]; then
|
|
1073
|
+
echo "Generated localnet transport overlay enabled. Starting ledger-only compose stack directly."
|
|
1074
|
+
else
|
|
1075
|
+
echo "start-local-ledger target not found. Starting ledger-only compose stack directly."
|
|
1076
|
+
fi
|
|
882
1077
|
start_ledger_stack "$auth_mode"
|
|
883
1078
|
if [[ "$(resolve_es256_enabled)" == "1" ]]; then
|
|
884
1079
|
echo "ES256 bearer token written to $LOCALNET_ES256_TOKEN_PATH"
|
package/node/stop-local.sh
CHANGED
|
@@ -92,6 +92,19 @@ es256_runtime_dir() {
|
|
|
92
92
|
printf '%s\n' "${START_LOCAL_ES256_RUNTIME_DIR:-$REPO_ROOT/.generated/localnet-es256}"
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
resolve_tls_enabled() {
|
|
96
|
+
local value="${LOCALNET_TLS:-0}"
|
|
97
|
+
if [[ "$value" != "0" && "$value" != "1" ]]; then
|
|
98
|
+
echo "LOCALNET_TLS must be 0 or 1." >&2
|
|
99
|
+
return 1
|
|
100
|
+
fi
|
|
101
|
+
printf '%s\n' "$value"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
tls_runtime_dir() {
|
|
105
|
+
printf '%s\n' "${START_LOCAL_TLS_RUNTIME_DIR:-$REPO_ROOT/.generated/localnet-tls}"
|
|
106
|
+
}
|
|
107
|
+
|
|
95
108
|
append_es256_args() {
|
|
96
109
|
local -n compose_args_ref="$1"
|
|
97
110
|
if [[ "$(resolve_es256_enabled)" == "1" ]]; then
|
|
@@ -102,6 +115,16 @@ append_es256_args() {
|
|
|
102
115
|
fi
|
|
103
116
|
}
|
|
104
117
|
|
|
118
|
+
append_tls_args() {
|
|
119
|
+
local -n compose_args_ref="$1"
|
|
120
|
+
if [[ "$(resolve_tls_enabled)" == "1" ]]; then
|
|
121
|
+
local compose_file="$(tls_runtime_dir)/compose-localnet.yaml"
|
|
122
|
+
if [[ -f "$compose_file" ]]; then
|
|
123
|
+
compose_args_ref+=( -f "$compose_file" )
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
}
|
|
127
|
+
|
|
105
128
|
resolve_docker_compose_cmd() {
|
|
106
129
|
if (( ${#DOCKER_COMPOSE_CMD[@]} > 0 )); then
|
|
107
130
|
return 0
|
|
@@ -177,6 +200,7 @@ stop_ledger_stack() {
|
|
|
177
200
|
fi
|
|
178
201
|
|
|
179
202
|
append_existing_extra_participant_args compose_args
|
|
203
|
+
append_tls_args compose_args
|
|
180
204
|
append_es256_args compose_args
|
|
181
205
|
docker_compose "${compose_args[@]}" down -v --remove-orphans
|
|
182
206
|
}
|
|
@@ -190,7 +214,7 @@ if [[ ! -f .env.local ]]; then
|
|
|
190
214
|
exit 0
|
|
191
215
|
fi
|
|
192
216
|
|
|
193
|
-
if [[ "$(resolve_es256_enabled)" != "1" ]] && make_target_exists stop-local-ledger; then
|
|
217
|
+
if [[ "$(resolve_es256_enabled)" != "1" && "$(resolve_tls_enabled)" != "1" ]] && make_target_exists stop-local-ledger; then
|
|
194
218
|
make stop-local-ledger
|
|
195
219
|
else
|
|
196
220
|
auth_mode="$(read_env_value AUTH_MODE || true)"
|
package/node/test-start-local.sh
CHANGED
|
@@ -32,12 +32,17 @@ run_case() {
|
|
|
32
32
|
local cn_quickstart_dir_override="${6:-}"
|
|
33
33
|
local repo_root_env_contents="${7:-}"
|
|
34
34
|
local es256_enabled="${8:-0}"
|
|
35
|
+
local tls_enabled="${9:-0}"
|
|
36
|
+
local tls_cert_chain_path="${10:-}"
|
|
37
|
+
local tls_private_key_path="${11:-}"
|
|
38
|
+
local tls_ca_cert_path="${12:-}"
|
|
39
|
+
local expected_status="${13:-0}"
|
|
35
40
|
local quickstart_dir="$tmpdir/quickstart"
|
|
36
41
|
local quickstart_root_dir="$tmpdir/cn-quickstart"
|
|
37
42
|
local stubbin="$tmpdir/bin"
|
|
38
43
|
local generated_dir="$tmpdir/generated"
|
|
39
44
|
|
|
40
|
-
rm -rf "$quickstart_dir" "$quickstart_root_dir" "$stubbin" "$generated_dir"
|
|
45
|
+
rm -rf "$quickstart_dir" "$quickstart_root_dir" "$stubbin" "$generated_dir" "$tmpdir/tls"
|
|
41
46
|
mkdir -p \
|
|
42
47
|
"$quickstart_root_dir" \
|
|
43
48
|
"$quickstart_dir/docker/modules/localnet/env" \
|
|
@@ -145,6 +150,7 @@ EOF
|
|
|
145
150
|
chmod +x "$stubbin/docker-compose"
|
|
146
151
|
|
|
147
152
|
local output
|
|
153
|
+
local status=0
|
|
148
154
|
output="$(
|
|
149
155
|
if [[ -n "$repo_root_env_contents" ]]; then
|
|
150
156
|
printf '%s\n' "$repo_root_env_contents" > "$REPO_ENV_FILE"
|
|
@@ -158,20 +164,39 @@ EOF
|
|
|
158
164
|
TERM="${TERM:-dumb}" \
|
|
159
165
|
START_LOCAL_GENERATED_DIR="$generated_dir" \
|
|
160
166
|
START_LOCAL_ES256_RUNTIME_DIR="$tmpdir/es256" \
|
|
167
|
+
START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
|
|
161
168
|
LOCALNET_ES256_JWT="$es256_enabled" \
|
|
169
|
+
LOCALNET_TLS="$tls_enabled" \
|
|
170
|
+
LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
|
|
171
|
+
LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
|
|
172
|
+
LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
|
|
162
173
|
EXTRA_PARTICIPANTS="$extra_participants" \
|
|
163
174
|
PATH="$stubbin:$PATH" \
|
|
164
|
-
bash ./start-local.sh
|
|
175
|
+
bash ./start-local.sh 2>&1
|
|
165
176
|
else
|
|
166
177
|
CN_QUICKSTART_DIR="${cn_quickstart_dir_override:-$quickstart_dir}" \
|
|
167
178
|
START_LOCAL_GENERATED_DIR="$generated_dir" \
|
|
168
179
|
START_LOCAL_ES256_RUNTIME_DIR="$tmpdir/es256" \
|
|
180
|
+
START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
|
|
169
181
|
LOCALNET_ES256_JWT="$es256_enabled" \
|
|
182
|
+
LOCALNET_TLS="$tls_enabled" \
|
|
183
|
+
LOCALNET_TLS_CERT_CHAIN_PATH="$tls_cert_chain_path" \
|
|
184
|
+
LOCALNET_TLS_PRIVATE_KEY_PATH="$tls_private_key_path" \
|
|
185
|
+
LOCALNET_TLS_CA_CERT_PATH="$tls_ca_cert_path" \
|
|
170
186
|
EXTRA_PARTICIPANTS="$extra_participants" \
|
|
171
187
|
PATH="$stubbin:$PATH" \
|
|
172
|
-
bash ./start-local.sh
|
|
188
|
+
bash ./start-local.sh 2>&1
|
|
173
189
|
fi
|
|
174
|
-
)"
|
|
190
|
+
)" || status=$?
|
|
191
|
+
|
|
192
|
+
if [[ "$expected_status" == "0" && "$status" != "0" ]]; then
|
|
193
|
+
printf 'expected successful start-local case, got status %s and output:\n%s\n' "$status" "$output" >&2
|
|
194
|
+
exit 1
|
|
195
|
+
fi
|
|
196
|
+
if [[ "$expected_status" != "0" && "$status" == "0" ]]; then
|
|
197
|
+
printf 'expected failing start-local case, got success and output:\n%s\n' "$output" >&2
|
|
198
|
+
exit 1
|
|
199
|
+
fi
|
|
175
200
|
|
|
176
201
|
if ! grep -Fxq "$expected_output" <<<"$output"; then
|
|
177
202
|
printf 'expected output line %q, got:\n%s\n' "$expected_output" "$output" >&2
|
|
@@ -190,6 +215,28 @@ assert_file_contains() {
|
|
|
190
215
|
fi
|
|
191
216
|
}
|
|
192
217
|
|
|
218
|
+
assert_file_contains_text() {
|
|
219
|
+
local path="$1"
|
|
220
|
+
local expected="$2"
|
|
221
|
+
|
|
222
|
+
if ! grep -Fq "$expected" "$path"; then
|
|
223
|
+
printf 'expected file %s to contain text %q, got:\n' "$path" "$expected" >&2
|
|
224
|
+
cat "$path" >&2
|
|
225
|
+
exit 1
|
|
226
|
+
fi
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
assert_file_mode() {
|
|
230
|
+
local path="$1"
|
|
231
|
+
local expected="$2"
|
|
232
|
+
local actual
|
|
233
|
+
actual="$(stat -c '%a' "$path")"
|
|
234
|
+
if [[ "$actual" != "$expected" ]]; then
|
|
235
|
+
printf 'expected file %s mode %s, got %s\n' "$path" "$expected" "$actual" >&2
|
|
236
|
+
exit 1
|
|
237
|
+
fi
|
|
238
|
+
}
|
|
239
|
+
|
|
193
240
|
run_repo_root_env_case() {
|
|
194
241
|
local quickstart_dir="$tmpdir/quickstart"
|
|
195
242
|
local quickstart_root_dir="$tmpdir/custom-quickstart-root"
|
|
@@ -351,4 +398,54 @@ assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf"
|
|
|
351
398
|
assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" ' validator-party-hint = "${EXTRA_VALIDATOR_1_PARTY_HINT}"'
|
|
352
399
|
assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" ' domains.global.buy-extra-traffic {'
|
|
353
400
|
assert_file_contains "$tmpdir/generated/additional-config.extra-validators.conf" 'canton.sv-apps.sv.expected-validator-onboardings += { secret = "${EXTRA_VALIDATOR_3_ONBOARDING_SECRET}" }'
|
|
401
|
+
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
|
|
402
|
+
assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.app-provider.ledger-api.tls {'
|
|
403
|
+
assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.app-provider.admin-api.tls {'
|
|
404
|
+
assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.app-user.ledger-api.tls {'
|
|
405
|
+
assert_file_contains_text "$tmpdir/tls/canton-tls.conf" 'canton.participants.sv.admin-api.tls {'
|
|
406
|
+
assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/server.key:ro'
|
|
407
|
+
assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/ca.crt:ro'
|
|
408
|
+
assert_file_mode "$tmpdir/tls/server.key" 600
|
|
409
|
+
assert_file_mode "$tmpdir/tls/ca.key" 600
|
|
410
|
+
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
|
|
411
|
+
assert_file_contains_text "$tmpdir/generated/additional-config.extra-participants.conf" 'canton.participants.extra-1.ledger-api.tls {'
|
|
412
|
+
assert_file_contains_text "$tmpdir/generated/additional-config.extra-participants.conf" 'canton.participants.extra-2.admin-api.tls {'
|
|
413
|
+
|
|
414
|
+
mkdir -p "$tmpdir/supplied"
|
|
415
|
+
openssl genrsa -out "$tmpdir/supplied/ca.key" 2048 >/dev/null 2>&1
|
|
416
|
+
openssl req -x509 -new -sha256 -days 3650 \
|
|
417
|
+
-key "$tmpdir/supplied/ca.key" \
|
|
418
|
+
-subj '/CN=supplied-localnet-ca' \
|
|
419
|
+
-addext 'basicConstraints=critical,CA:TRUE' \
|
|
420
|
+
-addext 'keyUsage=critical,keyCertSign,cRLSign' \
|
|
421
|
+
-out "$tmpdir/supplied/ca.crt" >/dev/null 2>&1
|
|
422
|
+
openssl genrsa -out "$tmpdir/supplied/server.key" 2048 >/dev/null 2>&1
|
|
423
|
+
openssl req -new -sha256 -key "$tmpdir/supplied/server.key" \
|
|
424
|
+
-subj '/CN=localhost' -out "$tmpdir/supplied/server.csr" >/dev/null 2>&1
|
|
425
|
+
printf '%s\n' \
|
|
426
|
+
'[server_ext]' \
|
|
427
|
+
'basicConstraints = CA:FALSE' \
|
|
428
|
+
'keyUsage = digitalSignature, keyEncipherment' \
|
|
429
|
+
'extendedKeyUsage = serverAuth' \
|
|
430
|
+
'subjectAltName = DNS:localhost, DNS:canton, IP:127.0.0.1' \
|
|
431
|
+
> "$tmpdir/supplied/server-extensions.cnf"
|
|
432
|
+
openssl x509 -req -sha256 -days 3650 \
|
|
433
|
+
-in "$tmpdir/supplied/server.csr" \
|
|
434
|
+
-CA "$tmpdir/supplied/ca.crt" -CAkey "$tmpdir/supplied/ca.key" -CAcreateserial \
|
|
435
|
+
-out "$tmpdir/supplied/server.crt" \
|
|
436
|
+
-extfile "$tmpdir/supplied/server-extensions.cnf" -extensions server_ext >/dev/null 2>&1
|
|
437
|
+
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"
|
|
438
|
+
if [[ -e "$tmpdir/tls/server.key" || -e "$tmpdir/tls/ca.key" ]]; then
|
|
439
|
+
echo 'supplied TLS mode unexpectedly generated private material' >&2
|
|
440
|
+
exit 1
|
|
441
|
+
fi
|
|
442
|
+
assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" "$tmpdir/supplied/server.key:/app/localnet-tls/server.key:ro"
|
|
443
|
+
openssl genrsa -out "$tmpdir/supplied/mismatch.key" 2048 >/dev/null 2>&1
|
|
444
|
+
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
|
|
445
|
+
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
|
|
446
|
+
run_case $'.PHONY: start\nstart:\n' 'LOCALNET_TLS must be 0 or 1.' shared-secret default 0 '' '' 0 invalid '' '' '' 1
|
|
447
|
+
run_case $'.PHONY: start\nstart:\n' 'ES256 bearer token written to '"$tmpdir"'/es256/ledger-api-user.token' shared-secret default 0 '' '' 1 1
|
|
448
|
+
assert_file_contains_text "$tmpdir/es256/canton-es256.conf" 'include file("/app/localnet-tls.conf")'
|
|
449
|
+
assert_file_contains_text "$tmpdir/es256/compose-es256.yaml" '/app/es256-certificate.pem:ro'
|
|
450
|
+
assert_file_contains_text "$tmpdir/tls/compose-localnet.yaml" '/app/localnet-tls/server.crt:ro'
|
|
354
451
|
run_repo_root_env_case
|
package/node/test-stop-local.sh
CHANGED
|
@@ -14,6 +14,7 @@ run_case() {
|
|
|
14
14
|
local expected_output="$2"
|
|
15
15
|
local auth_mode="${3:-shared-secret}"
|
|
16
16
|
local docker_mode="${4:-compose-v2}"
|
|
17
|
+
local tls_enabled="${5:-0}"
|
|
17
18
|
local quickstart_dir="$tmpdir/quickstart"
|
|
18
19
|
local stubbin="$tmpdir/bin"
|
|
19
20
|
local generated_dir="$tmpdir/generated-stop"
|
|
@@ -26,6 +27,10 @@ run_case() {
|
|
|
26
27
|
"$quickstart_dir/docker/modules/keycloak" \
|
|
27
28
|
"$stubbin" \
|
|
28
29
|
"$generated_dir"
|
|
30
|
+
if [[ "$tls_enabled" == "1" ]]; then
|
|
31
|
+
mkdir -p "$tmpdir/tls"
|
|
32
|
+
printf 'services:\n' > "$tmpdir/tls/compose-localnet.yaml"
|
|
33
|
+
fi
|
|
29
34
|
|
|
30
35
|
printf '%s\n' "$makefile_targets" > "$quickstart_dir/Makefile"
|
|
31
36
|
printf 'DOCKER_NETWORK=quickstart\nSPLICE_VERSION=0.6.5\n' > "$quickstart_dir/.env"
|
|
@@ -95,6 +100,8 @@ EOF
|
|
|
95
100
|
cd "$SCRIPT_DIR"
|
|
96
101
|
CN_QUICKSTART_DIR="$quickstart_dir" \
|
|
97
102
|
START_LOCAL_GENERATED_DIR="$generated_dir" \
|
|
103
|
+
START_LOCAL_TLS_RUNTIME_DIR="$tmpdir/tls" \
|
|
104
|
+
LOCALNET_TLS="$tls_enabled" \
|
|
98
105
|
PATH="$stubbin:$PATH" \
|
|
99
106
|
bash ./stop-local.sh
|
|
100
107
|
)"
|
|
@@ -109,4 +116,4 @@ run_case $'.PHONY: stop-local-ledger\nstop-local-ledger:\n' 'stub make stop-loca
|
|
|
109
116
|
run_case $'.PHONY: stop\nstop:\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'
|
|
110
117
|
run_case $'.PHONY: stop\nstop:\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
|
|
111
118
|
run_case $'.PHONY: stop\nstop:\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
|
|
112
|
-
|
|
119
|
+
run_case $'.PHONY: stop-local-ledger\nstop-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 compose-v2 1
|