@distrohelena/canton-typescript-sdk 0.1.33 → 0.1.36
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 +211 -18
- package/dist/cjs/client/external-party-activation-client.js +20 -10
- package/dist/cjs/core/errors/active-contracts-traversal-error.js +12 -0
- package/dist/cjs/core/polling/poll-until-async.js +26 -0
- package/dist/cjs/core/types/active-contracts-traversal-options.js +26 -0
- package/dist/cjs/core/types/command-deduplication-period.js +2 -0
- package/dist/cjs/core/types/operation-deadline.js +42 -0
- package/dist/cjs/core/types/requests/allocate-party-request.js +2 -0
- package/dist/cjs/core/types/requests/finalize-decentralized-party-request.js +6 -0
- package/dist/cjs/core/types/requests/submit-command-request.js +43 -0
- package/dist/cjs/core/types/requests/wait-for-party-hosting-request.js +40 -0
- package/dist/cjs/index.js +13 -27
- package/dist/cjs/query/grpc/grpc-contract-query-client.js +33 -16
- package/dist/cjs/services/party-management/decentralized-party-lifecycle.js +12 -1
- package/dist/cjs/services/party-management/party-management-service-client.js +3 -0
- package/dist/cjs/services/state/state-service-client.js +57 -1
- package/dist/cjs/services/topology-aggregation/topology-aggregation-service-client.js +36 -0
- package/dist/cjs/transports/grpc/grpc-channel-factory.js +5 -7
- package/dist/cjs/transports/grpc/grpc-transport.js +31 -15
- package/dist/cjs/transports/grpc/mappers/command-deduplication-mapper.js +22 -0
- package/dist/cjs/transports/grpc/mappers/commands-mapper.js +3 -4
- package/dist/cjs/transports/grpc/mappers/interactive-command-mapper.js +5 -3
- package/dist/cjs/transports/grpc/mappers/parties-mapper.js +1 -12
- package/dist/cjs/transports/json/mappers/commands-mapper.js +5 -1
- package/dist/cjs/transports/json/mappers/parties-mapper.js +1 -0
- package/dist/client/external-party-activation-client.js +20 -10
- package/dist/client/external-party-activation-response.d.ts +1 -1
- package/dist/core/errors/active-contracts-traversal-error.d.ts +5 -0
- package/dist/core/errors/active-contracts-traversal-error.js +8 -0
- package/dist/core/polling/poll-until-async.d.ts +10 -0
- package/dist/core/polling/poll-until-async.js +23 -0
- package/dist/core/transports/transport.interface.d.ts +11 -3
- package/dist/core/types/active-contracts-traversal-options.d.ts +11 -0
- package/dist/core/types/active-contracts-traversal-options.js +22 -0
- package/dist/core/types/command-deduplication-period.d.ts +7 -0
- package/dist/core/types/command-deduplication-period.js +1 -0
- package/dist/core/types/operation-deadline.d.ts +13 -0
- package/dist/core/types/operation-deadline.js +38 -0
- package/dist/core/types/requests/allocate-party-request.d.ts +2 -0
- package/dist/core/types/requests/allocate-party-request.js +2 -0
- package/dist/core/types/requests/finalize-decentralized-party-request.d.ts +6 -0
- package/dist/core/types/requests/finalize-decentralized-party-request.js +6 -0
- package/dist/core/types/requests/submit-command-request.d.ts +5 -0
- package/dist/core/types/requests/submit-command-request.js +43 -0
- package/dist/core/types/requests/wait-for-party-hosting-request.d.ts +14 -0
- package/dist/core/types/requests/wait-for-party-hosting-request.js +36 -0
- package/dist/index.d.ts +5 -11
- package/dist/index.js +4 -11
- package/dist/query/grpc/grpc-contract-query-client.js +33 -16
- package/dist/services/party-management/decentralized-party-lifecycle.d.ts +1 -1
- package/dist/services/party-management/decentralized-party-lifecycle.js +12 -1
- package/dist/services/party-management/party-management-service-client.js +3 -0
- package/dist/services/state/state-service-client.d.ts +5 -1
- package/dist/services/state/state-service-client.js +57 -1
- package/dist/services/topology-aggregation/topology-aggregation-service-client.d.ts +4 -1
- package/dist/services/topology-aggregation/topology-aggregation-service-client.js +36 -0
- package/dist/services/topology-manager-read/topology-manager-read-service-client.d.ts +3 -1
- package/dist/services/user-management/user-management-service-client.d.ts +7 -1
- package/dist/transports/grpc/grpc-channel-factory.d.ts +0 -1
- package/dist/transports/grpc/grpc-channel-factory.js +5 -7
- package/dist/transports/grpc/grpc-transport.d.ts +10 -3
- package/dist/transports/grpc/grpc-transport.js +31 -15
- package/dist/transports/grpc/mappers/command-deduplication-mapper.d.ts +5 -0
- package/dist/transports/grpc/mappers/command-deduplication-mapper.js +19 -0
- package/dist/transports/grpc/mappers/commands-mapper.js +3 -4
- package/dist/transports/grpc/mappers/interactive-command-mapper.js +5 -3
- package/dist/transports/grpc/mappers/parties-mapper.d.ts +3 -7
- package/dist/transports/grpc/mappers/parties-mapper.js +1 -10
- package/dist/transports/json/json-transport.d.ts +10 -5
- package/dist/transports/json/mappers/commands-mapper.js +5 -1
- package/dist/transports/json/mappers/parties-mapper.d.ts +1 -0
- package/dist/transports/json/mappers/parties-mapper.js +1 -0
- package/node/participant-358-synchronizer.mjs +33 -1
- package/node/start-local-participant-358.sh +33 -3
- package/node/test-participant-358-sidecar.sh +31 -1
- package/package.json +15 -1
- package/dist/cjs/core/types/health-check-status.js +0 -10
- package/dist/cjs/core/types/requests/get-ledger-api-version-request.js +0 -6
- package/dist/cjs/core/types/requests/get-package-references-request.js +0 -10
- package/dist/cjs/core/types/requests/get-participant-id-request.js +0 -7
- package/dist/cjs/core/types/requests/get-participant-status-request.js +0 -6
- package/dist/cjs/core/types/requests/health-check-request.js +0 -10
- package/dist/cjs/core/types/responses/get-ledger-api-version-response.js +0 -12
- package/dist/cjs/core/types/responses/get-package-references-response.js +0 -10
- package/dist/cjs/core/types/responses/get-participant-id-response.js +0 -10
- package/dist/cjs/core/types/responses/get-participant-status-response.js +0 -12
- package/dist/cjs/core/types/responses/health-check-response.js +0 -10
- package/dist/cjs/transports/grpc/mappers/health-mapper.js +0 -24
- package/dist/cjs/transports/grpc/mappers/participant-status-mapper.js +0 -58
- package/dist/core/types/health-check-status.d.ts +0 -6
- package/dist/core/types/health-check-status.js +0 -7
- package/dist/core/types/requests/get-ledger-api-version-request.d.ts +0 -2
- package/dist/core/types/requests/get-ledger-api-version-request.js +0 -2
- package/dist/core/types/requests/get-package-references-request.d.ts +0 -6
- package/dist/core/types/requests/get-package-references-request.js +0 -6
- package/dist/core/types/requests/get-participant-id-request.d.ts +0 -3
- package/dist/core/types/requests/get-participant-id-request.js +0 -3
- package/dist/core/types/requests/get-participant-status-request.d.ts +0 -2
- package/dist/core/types/requests/get-participant-status-request.js +0 -2
- package/dist/core/types/requests/health-check-request.d.ts +0 -6
- package/dist/core/types/requests/health-check-request.js +0 -6
- package/dist/core/types/responses/get-ledger-api-version-response.d.ts +0 -8
- package/dist/core/types/responses/get-ledger-api-version-response.js +0 -8
- package/dist/core/types/responses/get-package-references-response.d.ts +0 -7
- package/dist/core/types/responses/get-package-references-response.js +0 -6
- package/dist/core/types/responses/get-participant-id-response.d.ts +0 -6
- package/dist/core/types/responses/get-participant-id-response.js +0 -6
- package/dist/core/types/responses/get-participant-status-response.d.ts +0 -10
- package/dist/core/types/responses/get-participant-status-response.js +0 -8
- package/dist/core/types/responses/health-check-response.d.ts +0 -7
- package/dist/core/types/responses/health-check-response.js +0 -6
- package/dist/transports/grpc/mappers/health-mapper.d.ts +0 -5
- package/dist/transports/grpc/mappers/health-mapper.js +0 -21
- package/dist/transports/grpc/mappers/participant-status-mapper.d.ts +0 -5
- package/dist/transports/grpc/mappers/participant-status-mapper.js +0 -54
package/README.md
CHANGED
|
@@ -92,6 +92,178 @@ topology shape: a serial-1 decentralized namespace definition, one self-root
|
|
|
92
92
|
namespace certificate per owner, and a PartyToParticipant containing the party
|
|
93
93
|
signing key. No deprecated PartyToKeyMapping is created.
|
|
94
94
|
|
|
95
|
+
The SDK preserves `identityProviderId`, `userId`, and `waitForAllocation`
|
|
96
|
+
through decentralized prepare/finalize. Canton ignores `waitForAllocation` for
|
|
97
|
+
decentralized parties, so the example explicitly calls
|
|
98
|
+
`topologyAggregationService.waitForPartyHostingAsync(...)` to prove that the
|
|
99
|
+
expected participant is hosting the party on the expected synchronizer. That
|
|
100
|
+
aggregate topology check is the same on Participant 3.5.7 and 3.5.8.
|
|
101
|
+
|
|
102
|
+
## Standalone TypeScript examples
|
|
103
|
+
|
|
104
|
+
The repository includes runnable TypeScript examples for a local Canton
|
|
105
|
+
participant. Check them before running a lifecycle:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run examples:check
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The setup and party examples are available individually:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run example:init
|
|
115
|
+
npm run example:tls
|
|
116
|
+
npm run example:jwt
|
|
117
|
+
npm run example:party:hosted
|
|
118
|
+
npm run example:party:external
|
|
119
|
+
npm run example:party:decentralized
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
For the application lifecycle, run these in order:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm run example:dar:upload
|
|
126
|
+
npm run example:contract:create-exercise
|
|
127
|
+
npm run example:contract:query
|
|
128
|
+
npm run example:updates:stream
|
|
129
|
+
npm run example:user:rights
|
|
130
|
+
npm run example:topology:party-hosting
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Workflow examples
|
|
134
|
+
|
|
135
|
+
The seven workflow examples are standalone proofs, not a sequence:
|
|
136
|
+
each uploads or verifies the fixture DAR, resolves a party, reads the
|
|
137
|
+
participant status, and creates its own run-scoped data. First make a Canton
|
|
138
|
+
participant available and verify the source with `npm run examples:check`; the
|
|
139
|
+
default endpoints and authentication environment variables are documented below.
|
|
140
|
+
The pruning preflight is a separate read-only operator check and does none of
|
|
141
|
+
those setup or mutation steps. Run any example independently:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npm run example:workflow:atomic
|
|
145
|
+
npm run example:workflow:retry
|
|
146
|
+
npm run example:workflow:resume
|
|
147
|
+
npm run example:workflow:stale-contract
|
|
148
|
+
npm run example:workflow:command-completion
|
|
149
|
+
npm run example:workflow:contract-lifecycle-audit
|
|
150
|
+
npm run example:workflow:update-lookup-reconciliation
|
|
151
|
+
npm run example:workflow:pruning-preflight
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Those seven established stateful workflows intentionally leave durable state behind. A missing `SDK_EXAMPLE_PARTY`
|
|
155
|
+
causes fallback party allocation, which creates durable topology state; every
|
|
156
|
+
one also creates durable contracts. Set `SDK_EXAMPLE_PARTY` to an existing
|
|
157
|
+
party to rerun the established workflows against that party and avoid fallback
|
|
158
|
+
allocation. The fixture DAR remains installed after a run.
|
|
159
|
+
|
|
160
|
+
The completion-correlation workflow (`npm run example:workflow:command-completion`)
|
|
161
|
+
is a standalone successful proof that creates durable Message state. It uses the
|
|
162
|
+
same normal `SDK_EXAMPLE_*` configuration: `SDK_EXAMPLE_LEDGER_ENDPOINT`,
|
|
163
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`,
|
|
164
|
+
`SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`,
|
|
165
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`,
|
|
166
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`,
|
|
167
|
+
`SDK_EXAMPLE_TLS_ROOT_CERTIFICATE`, `SDK_EXAMPLE_PARTY`,
|
|
168
|
+
`SDK_EXAMPLE_PARTY_PREFIX`, and `SDK_EXAMPLE_TIMEOUT_MS`.
|
|
169
|
+
`SDK_EXAMPLE_USER_ID` is mandatory: absent or blank input is rejected, while
|
|
170
|
+
every nonblank value is preserved untrimmed and exactly submitted and exactly
|
|
171
|
+
matched in the completion. With bearer authentication, the configured declared
|
|
172
|
+
user must equal the token's Ledger API user/subject; the example does not inspect
|
|
173
|
+
the token. It keeps the ledger end as its saved exclusive offset and begins the
|
|
174
|
+
first stream read before submission.
|
|
175
|
+
No public wait-for-command-completion helper or API is introduced; the
|
|
176
|
+
correlation helper remains example-only.
|
|
177
|
+
The completion-correlation example asserts successful correlation only; it does
|
|
178
|
+
not assert rejected-command correlation. On both participant observations, the
|
|
179
|
+
stream-first rejected-command probes observed no exact completion before their
|
|
180
|
+
bounded stream transport errors.
|
|
181
|
+
|
|
182
|
+
The contract-lifecycle audit workflow (`npm run example:workflow:contract-lifecycle-audit`) is a standalone gRPC-only proof. It uses the normal `SDK_EXAMPLE_*` endpoint, authentication, party, and timeout configuration: `SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`, `SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTY`, `SDK_EXAMPLE_PARTY_PREFIX`, and `SDK_EXAMPLE_TIMEOUT_MS`. An explicit `SDK_EXAMPLE_PARTY` is reused; otherwise fallback allocation creates durable topology. The fixture upload leaves a durable DAR, and the workflow leaves durable contracts. It uses the alpha ContractService to prove the original active Message before replacement and the replacement active Message afterward, then uses EventQuery for the original contract's create/archive history. It makes no post-archive ContractService claim for the original.
|
|
183
|
+
|
|
184
|
+
The update-lookup reconciliation workflow (`npm run example:workflow:update-lookup-reconciliation`) is a standalone gRPC-only proof that observes one exact self-party Message transaction from `UpdateService.GetUpdates`, then immediately reconciles it through `getUpdateById` and `getUpdateByOffset`. It uses the normal `SDK_EXAMPLE_*` endpoint, authentication, party, and timeout configuration, including `SDK_EXAMPLE_PARTY` and `SDK_EXAMPLE_TIMEOUT_MS`; first run `npm run examples:check` and make an authenticated participant available. An explicit party is reused, while fallback allocation creates durable topology; the fixture upload leaves a durable DAR and the workflow leaves durable contracts. The same unchanged implementation is tested against authenticated Participant 3.5.7 and the isolated Participant 3.5.8 sidecar, in default-party and explicit-party modes.
|
|
185
|
+
|
|
186
|
+
The pruning-preflight workflow (`npm run example:workflow:pruning-preflight`) is a standalone gRPC-only, read-only operator check. It requires `SDK_EXAMPLE_OFFSET` to be a canonical positive decimal integer and uses the normal endpoint, authentication, and timeout variables: `SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`, `SDK_EXAMPLE_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`, `SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, `SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN`, and `SDK_EXAMPLE_TIMEOUT_MS`. The participant-admin credential is required for the schedule and safe-pruning context reads. Its safe-pruning context request sends the saved ledger end and a validated current timestamp encoded in `beforeOrAt`; it leaves commitment-state absent. It does not mutate the participant or create durable state: no party, DAR, command, update query, schedule change, or pruning request is made. The later participant watermark classifies the supplied offset as `alreadyPruned`, `beyondLedgerEnd`, or `notObservedPruned`; all-divulged watermarks and schedule/safe-pruning context are reported separately and do not alter that result. `notObservedPruned` is not proven queryable, because pruning can race after the later observation and other query preconditions can still fail. The unchanged implementation is supported on Participant 3.5.7 and the isolated Participant 3.5.8 sidecar.
|
|
187
|
+
|
|
188
|
+
Each of the seven established stateful workflows prints its actor plus the full participant version returned by the
|
|
189
|
+
authenticated status API, its parsed release core, and its selected path:
|
|
190
|
+
`Participant version:`, `Release core:`, and `Compatibility path:`. The current
|
|
191
|
+
stateful-workflow implementation uses one common-code path for release cores 3.5.7 and 3.5.8. It
|
|
192
|
+
adds a version-specific behavioral difference only after live evidence proves
|
|
193
|
+
one; it does not infer compatibility from a container tag or endpoint.
|
|
194
|
+
|
|
195
|
+
- `example:workflow:atomic` first proves that an invalid choice is rejected,
|
|
196
|
+
then proves an atomic create-and-exercise by reading the created replacement
|
|
197
|
+
and its exact text.
|
|
198
|
+
- `example:workflow:retry` submits a caller-controlled command ID with a
|
|
199
|
+
deduplication duration, retries the exact same request, classifies the
|
|
200
|
+
duplicate outcome, and proves that exactly one matching contract is active.
|
|
201
|
+
- `example:workflow:resume` saves the ledger end before its post-offset create,
|
|
202
|
+
proves the intentionally idle stream timeout, then resumes exclusively after
|
|
203
|
+
that saved offset and rejects a pre-offset contract if it appears.
|
|
204
|
+
- `example:workflow:stale-contract` proves archive/replacement state and then
|
|
205
|
+
proves that exercising the archived contract is rejected.
|
|
206
|
+
|
|
207
|
+
Expected failures are accepted only through structured error classification:
|
|
208
|
+
gRPC status code, decoded status, operation, and the selected compatibility
|
|
209
|
+
path—not prose matching. The retry example uses one explicit command ID and
|
|
210
|
+
deduplication period for the exact same request; changing either value is a new
|
|
211
|
+
request and is not a retry proof. The resume example treats the saved offset as
|
|
212
|
+
exclusive, so its resumed stream must observe only updates after the saved
|
|
213
|
+
ledger end.
|
|
214
|
+
|
|
215
|
+
The seven established stateful workflow sources and unit contracts were developed
|
|
216
|
+
and live-tested against authenticated Participant 3.5.7 and the isolated
|
|
217
|
+
Participant 3.5.8. Both final-tree matrices selected the same unchanged implementation and common
|
|
218
|
+
compatibility path. The normalized outcome comparison is identical: atomic
|
|
219
|
+
reports `invalidChoice` before its replacement proof, retry reports
|
|
220
|
+
`duplicateCommand` with one active contract, resume reports `idle-timeout` and
|
|
221
|
+
a post-offset update, and stale-contract reports `staleContract`.
|
|
222
|
+
|
|
223
|
+
For those seven established stateful workflows, the best multi-version path reads the authenticated full version, parses its
|
|
224
|
+
release core, and uses data-only structured compatibility for observed
|
|
225
|
+
outcomes. A behavioral difference is introduced only after live proof; it is
|
|
226
|
+
never inferred from a container tag, endpoint, or prose error message. For the
|
|
227
|
+
isolated 3.5.8 sidecar, use the SDK sidecar launcher's protected documented
|
|
228
|
+
credential refresh flow in a local child shell and refresh before expiry. Never
|
|
229
|
+
log its output or expose refreshed credentials beyond that child. Use the
|
|
230
|
+
documented `SDK_EXAMPLE_*` environment variables when running the workflow
|
|
231
|
+
commands.
|
|
232
|
+
|
|
233
|
+
By default, Ledger and Ledger Admin use `localhost:3901`; Participant Admin
|
|
234
|
+
uses `localhost:3902`. Override them with
|
|
235
|
+
`SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, and
|
|
236
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`. Use `SDK_EXAMPLE_BEARER_TOKEN` for a
|
|
237
|
+
shared bearer token, or set `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`,
|
|
238
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, and
|
|
239
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN` per surface. The examples also
|
|
240
|
+
accept `SDK_EXAMPLE_PARTY`, `SDK_EXAMPLE_USER_ID`, `SDK_EXAMPLE_SYNCHRONIZER`,
|
|
241
|
+
and `SDK_EXAMPLE_TIMEOUT_MS`; generated fallback party names use
|
|
242
|
+
`SDK_EXAMPLE_PARTY_PREFIX` when supplied. For TLS, set
|
|
243
|
+
`SDK_EXAMPLE_TLS_ROOT_CERTIFICATE` to a custom CA certificate path.
|
|
244
|
+
|
|
245
|
+
Some commands intentionally create durable localnet state: DAR upload installs
|
|
246
|
+
a package; create/exercise, query, and stream may allocate a fallback party and
|
|
247
|
+
create contracts; topology inspection may allocate a fallback party. User-rights
|
|
248
|
+
is read-only. These examples do not clean up durable state.
|
|
249
|
+
|
|
250
|
+
The uploaded asset is
|
|
251
|
+
`canton-explorer-debug-playground-0.1.0.dar`, the normal (not debug) Canton
|
|
252
|
+
Explorer Debug Playground DAR from
|
|
253
|
+
`/home/helena/dev/daml/canton-explorer/debug-playground/.daml/dist/canton-explorer-debug-playground-0.1.0.dar`.
|
|
254
|
+
Its Canton Explorer checkout commit is `750b28dd0ce4674e4368c12a6da1b5b5cbb00f88`,
|
|
255
|
+
its package-introduction commit is `abde077`, it is Apache-2.0 licensed, and
|
|
256
|
+
its SHA-256 is
|
|
257
|
+
`307cf7c52ac2770d1d1a2c5e1ec56a78ab7c70e7809c0cfb419abadb93cc6e29`.
|
|
258
|
+
|
|
259
|
+
The examples and their DAR are repository-only and excluded from the npm
|
|
260
|
+
tarball. The existing setup and decentralized-party examples were developed
|
|
261
|
+
and live-tested against Participant 3.5.7, then live-tested unchanged against
|
|
262
|
+
the isolated [Participant 3.5.8 sidecar](#optional-canton-358-participant-sidecar).
|
|
263
|
+
The workflow examples have completed 3.5.7 and 3.5.8 workflow matrices with
|
|
264
|
+
authenticated status evidence, the same unchanged implementation, and the
|
|
265
|
+
common compatibility path.
|
|
266
|
+
|
|
95
267
|
## Localnet launchers
|
|
96
268
|
|
|
97
269
|
The published package includes launchers for an existing CN Quickstart checkout.
|
|
@@ -133,13 +305,21 @@ Compose project, its Postgres container, and host ports `8901` (Ledger), `8902`
|
|
|
133
305
|
registered synchronizer via its Admin API, stores the exported connection
|
|
134
306
|
configuration in the sidecar runtime directory, and connects the sidecar with
|
|
135
307
|
its own Admin API. It generates a five-minute 3.5.8-compatible development JWT
|
|
136
|
-
at `.generated/participant-358/ledger-api-user.token
|
|
137
|
-
|
|
308
|
+
at `.generated/participant-358/ledger-api-user.token`. When the connection is
|
|
309
|
+
healthy, use the protected child-shell credential flow below to make the
|
|
310
|
+
live-test and example endpoint/token variables available without logging them.
|
|
311
|
+
Canton 3.5.8 enforces this short lifetime for the unsafe development JWT.
|
|
138
312
|
`cn-quickstart` is strictly read-only: this launcher never writes to, starts,
|
|
139
313
|
or stops the normal Quickstart stack.
|
|
140
314
|
|
|
141
|
-
|
|
142
|
-
the
|
|
315
|
+
Refresh short-lived credentials before expiry without restarting or otherwise
|
|
316
|
+
touching the running containers. Use the launcher's protected documented
|
|
317
|
+
credential refresh flow only in a local child shell; do not log its output or
|
|
318
|
+
expose refreshed credentials beyond that child. The runtime credential file
|
|
319
|
+
remains protected with mode `0600`.
|
|
320
|
+
|
|
321
|
+
After the protected credential flow completes, run the example inside that same
|
|
322
|
+
short-lived credential-scoped child shell:
|
|
143
323
|
|
|
144
324
|
```bash
|
|
145
325
|
npm run example:party:decentralized
|
|
@@ -151,11 +331,14 @@ localnet differs:
|
|
|
151
331
|
|
|
152
332
|
```bash
|
|
153
333
|
PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT=localhost:3902 \
|
|
154
|
-
PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN="$TOKEN" \
|
|
155
334
|
PARTICIPANT_358_NETWORK=quickstart \
|
|
156
335
|
canton-localnet-participant-358-start
|
|
157
336
|
```
|
|
158
337
|
|
|
338
|
+
Provide any required source-admin credential only through the protected
|
|
339
|
+
child-scoped credential mechanism described above; do not place credentials in
|
|
340
|
+
command lines or logs.
|
|
341
|
+
|
|
159
342
|
Use `PARTICIPANT_358_CANTON_IMAGE`, `PARTICIPANT_358_PROJECT_NAME`,
|
|
160
343
|
`PARTICIPANT_358_RUNTIME_DIR`, `PARTICIPANT_358_LEDGER_PORT`,
|
|
161
344
|
`PARTICIPANT_358_ADMIN_PORT`, and `PARTICIPANT_358_JSON_PORT` to make an
|
|
@@ -179,11 +362,12 @@ a self-signed certificate in `.generated/localnet-es256` at the package root. Se
|
|
|
179
362
|
use your own matching PEM private key and certificate.
|
|
180
363
|
|
|
181
364
|
The launcher writes a short-lived (ten-minute) token for `ledger-api-user` to
|
|
182
|
-
`ledger-api-user.token` in that runtime directory and prints its path.
|
|
183
|
-
|
|
365
|
+
`ledger-api-user.token` in that runtime directory and prints its path. In a
|
|
366
|
+
short-lived child shell, use a protected local credential mechanism to make the
|
|
367
|
+
token available without placing its value or a token-file read in a command
|
|
368
|
+
line or log. From within that same child shell, run the live SDK suite:
|
|
184
369
|
|
|
185
370
|
```bash
|
|
186
|
-
SDK_TEST_LEDGER_BEARER_TOKEN="$(cat .generated/localnet-es256/ledger-api-user.token)" \
|
|
187
371
|
npm run test:live
|
|
188
372
|
```
|
|
189
373
|
|
|
@@ -356,11 +540,11 @@ import {
|
|
|
356
540
|
BearerTokenAuthProvider,
|
|
357
541
|
CantonClient,
|
|
358
542
|
CantonClientOptions,
|
|
359
|
-
GetActiveContractsPageRequest,
|
|
360
543
|
HealthCheckRequest,
|
|
361
544
|
GetLedgerApiVersionRequest,
|
|
362
545
|
TransportKind,
|
|
363
546
|
} from "@distrohelena/canton-typescript-sdk";
|
|
547
|
+
import { ledgerApiV2 } from "@distrohelena/canton-typescript-sdk/protobuf";
|
|
364
548
|
|
|
365
549
|
const client = new CantonClient(
|
|
366
550
|
new CantonClientOptions({
|
|
@@ -393,14 +577,22 @@ const party = await client.partyManagementService.allocatePartyAsync(
|
|
|
393
577
|
}),
|
|
394
578
|
);
|
|
395
579
|
const contracts = await client.stateService.getActiveContractsPageAsync(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
580
|
+
ledgerApiV2.GetActiveContractsPageRequest.create({
|
|
581
|
+
eventFormat: {
|
|
582
|
+
filtersByParty: {
|
|
583
|
+
Alice: { cumulative: [] },
|
|
584
|
+
},
|
|
585
|
+
verbose: true,
|
|
586
|
+
},
|
|
399
587
|
}),
|
|
400
588
|
);
|
|
401
589
|
```
|
|
402
590
|
|
|
403
|
-
`stateService.getActiveContractsPageAsync(...)`
|
|
591
|
+
`stateService.getActiveContractsPageAsync(...)` is gRPC-only and accepts the generated Ledger API request, including its `eventFormat`, `activeAtOffset`, `maxPageSize`, and `pageToken` fields. Build party, template, and interface filters in `eventFormat`.
|
|
592
|
+
|
|
593
|
+
`stateService.getActiveContractsPagesAsync(...)` is the gRPC-only lazy, raw, bounded traversal API. It starts from the same generated request and yields raw `GetActiveContractsPageResponse` values one page at a time. The caller selects the shared `OperationDeadline`, maximum pages, and maximum contracts with `ActiveContractsTraversalOptions`; there is no collect-all wrapper. Transport errors from dispatched RPCs propagate unchanged. Traversal safety, invariant, and bound failures use `ActiveContractsTraversalError` codes, such as an inconsistent offset, repeated page token, or exceeded bound.
|
|
594
|
+
|
|
595
|
+
JSON does not implement either paginated gRPC API. Its existing `stateService.getActiveContractsAsync(...)` behavior remains the distinct JSON streaming read.
|
|
404
596
|
|
|
405
597
|
For interface views, do not use `contractService.getContractAsync(...)`. That contract lookup surface cannot return interface views; use `stateService` or `updateService` instead.
|
|
406
598
|
|
|
@@ -547,12 +739,13 @@ unsupported query features reject with `QueryCapabilityError`.
|
|
|
547
739
|
- `packageService.listVettedPackagesAsync(...)`: `grpc` only
|
|
548
740
|
- `commandService.submitAndWaitAsync(...)`: `json`, `grpc`
|
|
549
741
|
- `commandSubmissionService.submitAsync(...)`: reserved, currently unsupported
|
|
550
|
-
- `stateService.getActiveContractsPageAsync(...)`: `
|
|
551
|
-
- `stateService.
|
|
742
|
+
- `stateService.getActiveContractsPageAsync(...)`: `grpc` only
|
|
743
|
+
- `stateService.getActiveContractsPagesAsync(...)`: `grpc` only, lazy raw bounded traversal
|
|
744
|
+
- `stateService.getActiveContractsAsync(...)`: `json` only, existing distinct streaming read
|
|
552
745
|
- `updateService.getUpdatesAsync(...)`: `grpc` only
|
|
553
|
-
- `commandCompletionService`:
|
|
554
|
-
- `eventQueryService`:
|
|
555
|
-
- `contractService`:
|
|
746
|
+
- `commandCompletionService.getCompletionsAsync(...)`: `grpc` only, existing streaming API
|
|
747
|
+
- `eventQueryService.getEventsByContractIdAsync(...)`: `grpc` only; JSON rejects this request
|
|
748
|
+
- `contractService.getContractAsync(...)`: `grpc` only; JSON rejects this request
|
|
556
749
|
|
|
557
750
|
- Ledger Admin endpoint:
|
|
558
751
|
- `partyManagementService.allocatePartyAsync(...)`: `json`, `grpc`
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ExternalPartyActivationClient = void 0;
|
|
4
|
+
const list_party_to_participant_request_js_1 = require("../core/types/requests/list-party-to-participant-request.js");
|
|
5
|
+
const topology_base_query_js_1 = require("../core/types/topology/topology-base-query.js");
|
|
4
6
|
const topology_store_id_js_1 = require("../core/types/topology/topology-store-id.js");
|
|
5
7
|
const topology_js_1 = require("../transports/grpc/generated/canton/com/digitalasset/canton/protocol/v30/topology.js");
|
|
6
8
|
const external_party_activation_response_js_1 = require("./external-party-activation-response.js");
|
|
@@ -66,27 +68,35 @@ class ExternalPartyActivationClient {
|
|
|
66
68
|
}
|
|
67
69
|
async readStateAsync(request, options) {
|
|
68
70
|
const [activeResponse, proposalResponse] = await Promise.all([
|
|
69
|
-
this.sourceClient.topologyManagerReadService.listPartyToParticipantAsync({
|
|
70
|
-
baseQuery:
|
|
71
|
+
this.sourceClient.topologyManagerReadService.listPartyToParticipantAsync(new list_party_to_participant_request_js_1.ListPartyToParticipantRequest({
|
|
72
|
+
baseQuery: new topology_base_query_js_1.TopologyBaseQuery({
|
|
73
|
+
storeId: createSynchronizerStoreId(request.synchronizerId),
|
|
74
|
+
headState: true,
|
|
75
|
+
includeProposals: false,
|
|
76
|
+
}),
|
|
71
77
|
filterParty: request.partyId,
|
|
72
78
|
filterParticipant: "",
|
|
73
|
-
}, options),
|
|
74
|
-
this.sourceClient.topologyManagerReadService.listPartyToParticipantAsync({
|
|
75
|
-
baseQuery:
|
|
79
|
+
}), options),
|
|
80
|
+
this.sourceClient.topologyManagerReadService.listPartyToParticipantAsync(new list_party_to_participant_request_js_1.ListPartyToParticipantRequest({
|
|
81
|
+
baseQuery: new topology_base_query_js_1.TopologyBaseQuery({
|
|
82
|
+
storeId: createSynchronizerStoreId(request.synchronizerId),
|
|
83
|
+
headState: true,
|
|
84
|
+
includeProposals: true,
|
|
85
|
+
}),
|
|
76
86
|
filterParty: request.partyId,
|
|
77
87
|
filterParticipant: "",
|
|
78
|
-
}, options),
|
|
88
|
+
}), options),
|
|
79
89
|
]);
|
|
80
|
-
const active = activeResponse.results.find((item) => item.item
|
|
81
|
-
const proposal = proposalResponse.results.find((item) => item.item
|
|
90
|
+
const active = activeResponse.results.find((item) => item.item.party === request.partyId);
|
|
91
|
+
const proposal = proposalResponse.results.find((item) => item.item.party === request.partyId);
|
|
82
92
|
return {
|
|
83
|
-
active: active === undefined || active.context === undefined
|
|
93
|
+
active: active === undefined || active.context === undefined
|
|
84
94
|
? undefined
|
|
85
95
|
: {
|
|
86
96
|
context: active.context,
|
|
87
97
|
mapping: active.item,
|
|
88
98
|
},
|
|
89
|
-
proposal: proposal === undefined || proposal.context === undefined
|
|
99
|
+
proposal: proposal === undefined || proposal.context === undefined
|
|
90
100
|
? undefined
|
|
91
101
|
: {
|
|
92
102
|
context: proposal.context,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ActiveContractsTraversalError = void 0;
|
|
4
|
+
const canton_error_js_1 = require("./canton-error.js");
|
|
5
|
+
class ActiveContractsTraversalError extends canton_error_js_1.CantonError {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ActiveContractsTraversalError = ActiveContractsTraversalError;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pollUntilAsync = pollUntilAsync;
|
|
4
|
+
async function pollUntilAsync(init) {
|
|
5
|
+
const now = init.now ?? Date.now;
|
|
6
|
+
const sleepAsync = init.sleepAsync ?? defaultSleepAsync;
|
|
7
|
+
const deadline = now() + init.timeoutMs;
|
|
8
|
+
let lastObserved;
|
|
9
|
+
let firstRead = true;
|
|
10
|
+
while (firstRead || now() < deadline) {
|
|
11
|
+
firstRead = false;
|
|
12
|
+
lastObserved = await init.readAsync();
|
|
13
|
+
if (init.match(lastObserved)) {
|
|
14
|
+
return lastObserved;
|
|
15
|
+
}
|
|
16
|
+
const remainingMs = deadline - now();
|
|
17
|
+
if (remainingMs <= 0) {
|
|
18
|
+
throw init.createTimeoutError(lastObserved);
|
|
19
|
+
}
|
|
20
|
+
await sleepAsync(Math.min(init.pollIntervalMs, remainingMs));
|
|
21
|
+
}
|
|
22
|
+
throw init.createTimeoutError(lastObserved);
|
|
23
|
+
}
|
|
24
|
+
async function defaultSleepAsync(milliseconds) {
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ActiveContractsTraversalOptions = void 0;
|
|
4
|
+
const validation_error_js_1 = require("../errors/validation-error.js");
|
|
5
|
+
const operation_deadline_js_1 = require("./operation-deadline.js");
|
|
6
|
+
class ActiveContractsTraversalOptions {
|
|
7
|
+
deadline;
|
|
8
|
+
maxPages;
|
|
9
|
+
maxContracts;
|
|
10
|
+
constructor(init) {
|
|
11
|
+
if (!(init.deadline instanceof operation_deadline_js_1.OperationDeadline)) {
|
|
12
|
+
throw new validation_error_js_1.ValidationError("active contracts traversal deadline must be an OperationDeadline");
|
|
13
|
+
}
|
|
14
|
+
else if (!Number.isSafeInteger(init.maxPages) || init.maxPages <= 0) {
|
|
15
|
+
throw new validation_error_js_1.ValidationError("active contracts traversal maxPages must be a positive safe integer");
|
|
16
|
+
}
|
|
17
|
+
else if (!Number.isSafeInteger(init.maxContracts) || init.maxContracts <= 0) {
|
|
18
|
+
throw new validation_error_js_1.ValidationError("active contracts traversal maxContracts must be a positive safe integer");
|
|
19
|
+
}
|
|
20
|
+
this.deadline = init.deadline;
|
|
21
|
+
this.maxPages = init.maxPages;
|
|
22
|
+
this.maxContracts = init.maxContracts;
|
|
23
|
+
Object.freeze(this);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.ActiveContractsTraversalOptions = ActiveContractsTraversalOptions;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OperationDeadline = void 0;
|
|
4
|
+
const timeout_error_js_1 = require("../errors/timeout-error.js");
|
|
5
|
+
const validation_error_js_1 = require("../errors/validation-error.js");
|
|
6
|
+
const request_options_js_1 = require("./request-options.js");
|
|
7
|
+
class OperationDeadline {
|
|
8
|
+
endsAtMs;
|
|
9
|
+
now;
|
|
10
|
+
remainingMs;
|
|
11
|
+
constructor(init) {
|
|
12
|
+
if (!Number.isSafeInteger(init.timeoutMs) || init.timeoutMs <= 0) {
|
|
13
|
+
throw new validation_error_js_1.ValidationError("operation deadline timeout must be a positive safe integer");
|
|
14
|
+
}
|
|
15
|
+
this.now = init.now ?? Date.now;
|
|
16
|
+
const startedAtMs = this.safeNow();
|
|
17
|
+
this.endsAtMs = startedAtMs + init.timeoutMs;
|
|
18
|
+
if (!Number.isSafeInteger(this.endsAtMs)) {
|
|
19
|
+
throw new validation_error_js_1.ValidationError("operation deadline end time must be a safe integer");
|
|
20
|
+
}
|
|
21
|
+
this.remainingMs = init.timeoutMs;
|
|
22
|
+
}
|
|
23
|
+
remainingTimeoutMs() {
|
|
24
|
+
const computedRemainingMs = Math.max(0, this.endsAtMs - this.safeNow());
|
|
25
|
+
this.remainingMs = Math.min(this.remainingMs, computedRemainingMs);
|
|
26
|
+
if (this.remainingMs === 0) {
|
|
27
|
+
throw new timeout_error_js_1.TimeoutError("operation deadline has expired");
|
|
28
|
+
}
|
|
29
|
+
return this.remainingMs;
|
|
30
|
+
}
|
|
31
|
+
createRequestOptions() {
|
|
32
|
+
return new request_options_js_1.RequestOptions({ timeoutMs: this.remainingTimeoutMs() });
|
|
33
|
+
}
|
|
34
|
+
safeNow() {
|
|
35
|
+
const now = this.now();
|
|
36
|
+
if (!Number.isSafeInteger(now)) {
|
|
37
|
+
throw new validation_error_js_1.ValidationError("operation deadline clock must return a safe integer");
|
|
38
|
+
}
|
|
39
|
+
return now;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.OperationDeadline = OperationDeadline;
|
|
@@ -4,9 +4,11 @@ exports.AllocatePartyRequest = void 0;
|
|
|
4
4
|
class AllocatePartyRequest {
|
|
5
5
|
partyIdHint;
|
|
6
6
|
displayName;
|
|
7
|
+
userId;
|
|
7
8
|
constructor(init = {}) {
|
|
8
9
|
this.partyIdHint = init.partyIdHint;
|
|
9
10
|
this.displayName = init.displayName;
|
|
11
|
+
this.userId = init.userId;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
exports.AllocatePartyRequest = AllocatePartyRequest;
|
|
@@ -8,6 +8,9 @@ class PreparedDecentralizedParty {
|
|
|
8
8
|
decentralizedNamespace;
|
|
9
9
|
ownerThreshold;
|
|
10
10
|
partySigningThreshold;
|
|
11
|
+
identityProviderId;
|
|
12
|
+
waitForAllocation;
|
|
13
|
+
userId;
|
|
11
14
|
transactions;
|
|
12
15
|
signingRequests;
|
|
13
16
|
constructor(init) {
|
|
@@ -16,6 +19,9 @@ class PreparedDecentralizedParty {
|
|
|
16
19
|
this.decentralizedNamespace = init.decentralizedNamespace;
|
|
17
20
|
this.ownerThreshold = init.ownerThreshold;
|
|
18
21
|
this.partySigningThreshold = init.partySigningThreshold;
|
|
22
|
+
this.identityProviderId = init.identityProviderId;
|
|
23
|
+
this.waitForAllocation = init.waitForAllocation;
|
|
24
|
+
this.userId = init.userId;
|
|
19
25
|
this.transactions = [...(init.transactions ?? [])].map((transaction) => new prepared_topology_transaction_js_1.PreparedTopologyTransaction({
|
|
20
26
|
serializedTransaction: transaction.serializedTransaction,
|
|
21
27
|
transactionHash: transaction.transactionHash,
|
|
@@ -2,25 +2,68 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SubmitCommandRequest = void 0;
|
|
4
4
|
const validation_error_js_1 = require("../../errors/validation-error.js");
|
|
5
|
+
const ledgerStringPattern = /^[A-Za-z0-9#:\-_/ ]+$/;
|
|
6
|
+
const canonicalOffsetPattern = /^(0|[1-9][0-9]*)$/;
|
|
7
|
+
const maximumInt64Offset = "9223372036854775807";
|
|
5
8
|
class SubmitCommandRequest {
|
|
6
9
|
applicationId;
|
|
7
10
|
userId;
|
|
8
11
|
actAs;
|
|
9
12
|
readAs;
|
|
10
13
|
command;
|
|
14
|
+
commandId;
|
|
15
|
+
deduplicationPeriod;
|
|
11
16
|
disclosedContracts;
|
|
12
17
|
synchronizerId;
|
|
13
18
|
constructor(init) {
|
|
14
19
|
if (init.actAs.length === 0) {
|
|
15
20
|
throw new validation_error_js_1.ValidationError("submit requests require at least one actAs party");
|
|
16
21
|
}
|
|
22
|
+
else if (init.commandId !== undefined &&
|
|
23
|
+
(typeof init.commandId !== "string" ||
|
|
24
|
+
init.commandId.length > 255 ||
|
|
25
|
+
!ledgerStringPattern.test(init.commandId))) {
|
|
26
|
+
throw new validation_error_js_1.ValidationError("submit request command ID must be a LedgerString");
|
|
27
|
+
}
|
|
28
|
+
const deduplicationPeriod = freezeDeduplicationPeriod(init.deduplicationPeriod);
|
|
17
29
|
this.applicationId = init.applicationId;
|
|
18
30
|
this.userId = init.userId;
|
|
19
31
|
this.actAs = init.actAs;
|
|
20
32
|
this.readAs = init.readAs ?? [];
|
|
21
33
|
this.command = init.command;
|
|
34
|
+
this.commandId = init.commandId;
|
|
35
|
+
this.deduplicationPeriod = deduplicationPeriod;
|
|
22
36
|
this.disclosedContracts = init.disclosedContracts ?? [];
|
|
23
37
|
this.synchronizerId = init.synchronizerId;
|
|
24
38
|
}
|
|
25
39
|
}
|
|
26
40
|
exports.SubmitCommandRequest = SubmitCommandRequest;
|
|
41
|
+
function freezeDeduplicationPeriod(value) {
|
|
42
|
+
if (value === undefined) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
else if (typeof value !== "object" ||
|
|
46
|
+
value === null ||
|
|
47
|
+
Array.isArray(value)) {
|
|
48
|
+
throw new validation_error_js_1.ValidationError("submit request deduplication period is invalid");
|
|
49
|
+
}
|
|
50
|
+
else if (value.kind === "duration") {
|
|
51
|
+
if (typeof value.seconds !== "number" ||
|
|
52
|
+
!Number.isSafeInteger(value.seconds) ||
|
|
53
|
+
value.seconds <= 0) {
|
|
54
|
+
throw new validation_error_js_1.ValidationError("submit request duration deduplication seconds must be a positive safe integer");
|
|
55
|
+
}
|
|
56
|
+
return Object.freeze({ kind: "duration", seconds: value.seconds });
|
|
57
|
+
}
|
|
58
|
+
else if (value.kind !== "offset") {
|
|
59
|
+
throw new validation_error_js_1.ValidationError("submit request deduplication period is invalid");
|
|
60
|
+
}
|
|
61
|
+
if (typeof value.offset !== "string" ||
|
|
62
|
+
!canonicalOffsetPattern.test(value.offset) ||
|
|
63
|
+
value.offset.length > maximumInt64Offset.length ||
|
|
64
|
+
(value.offset.length === maximumInt64Offset.length &&
|
|
65
|
+
value.offset > maximumInt64Offset)) {
|
|
66
|
+
throw new validation_error_js_1.ValidationError("submit request offset deduplication period must be a canonical unsigned int64");
|
|
67
|
+
}
|
|
68
|
+
return Object.freeze({ kind: "offset", offset: value.offset });
|
|
69
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WaitForPartyHostingRequest = void 0;
|
|
4
|
+
const validation_error_js_1 = require("../../errors/validation-error.js");
|
|
5
|
+
class WaitForPartyHostingRequest {
|
|
6
|
+
partyId;
|
|
7
|
+
participantId;
|
|
8
|
+
synchronizerId;
|
|
9
|
+
pollIntervalMs;
|
|
10
|
+
timeoutMs;
|
|
11
|
+
constructor(init) {
|
|
12
|
+
const partyId = init.partyId.trim();
|
|
13
|
+
const participantId = init.participantId.trim();
|
|
14
|
+
const synchronizerId = init.synchronizerId.trim();
|
|
15
|
+
const pollIntervalMs = init.pollIntervalMs ?? 500;
|
|
16
|
+
const timeoutMs = init.timeoutMs ?? 30_000;
|
|
17
|
+
if (!partyId) {
|
|
18
|
+
throw new validation_error_js_1.ValidationError("party hosting wait requires a party ID");
|
|
19
|
+
}
|
|
20
|
+
else if (!participantId) {
|
|
21
|
+
throw new validation_error_js_1.ValidationError("party hosting wait requires a participant ID");
|
|
22
|
+
}
|
|
23
|
+
else if (!synchronizerId) {
|
|
24
|
+
throw new validation_error_js_1.ValidationError("party hosting wait requires a synchronizer ID");
|
|
25
|
+
}
|
|
26
|
+
else if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
|
|
27
|
+
throw new validation_error_js_1.ValidationError("party hosting wait timeout must be a positive safe integer");
|
|
28
|
+
}
|
|
29
|
+
else if (!Number.isSafeInteger(pollIntervalMs) ||
|
|
30
|
+
pollIntervalMs < 0) {
|
|
31
|
+
throw new validation_error_js_1.ValidationError("party hosting wait poll interval must be a non-negative safe integer");
|
|
32
|
+
}
|
|
33
|
+
this.partyId = partyId;
|
|
34
|
+
this.participantId = participantId;
|
|
35
|
+
this.synchronizerId = synchronizerId;
|
|
36
|
+
this.pollIntervalMs = pollIntervalMs;
|
|
37
|
+
this.timeoutMs = timeoutMs;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.WaitForPartyHostingRequest = WaitForPartyHostingRequest;
|