@distrohelena/canton-typescript-sdk 0.1.33 → 0.1.35
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 +169 -14
- 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 +1 -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 +1 -1
- package/dist/services/state/state-service-client.js +1 -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 +11 -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,145 @@ 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 four workflow examples are standalone proofs, not a sequence: each uploads
|
|
136
|
+
or verifies the fixture DAR, resolves a party, reads the participant status,
|
|
137
|
+
and creates its own run-scoped data. First make a Canton participant available
|
|
138
|
+
and verify the source with `npm run examples:check`; the default endpoints and
|
|
139
|
+
authentication environment variables are documented below. Run any example
|
|
140
|
+
independently:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm run example:workflow:atomic
|
|
144
|
+
npm run example:workflow:retry
|
|
145
|
+
npm run example:workflow:resume
|
|
146
|
+
npm run example:workflow:stale-contract
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
They intentionally leave durable state behind. A missing `SDK_EXAMPLE_PARTY`
|
|
150
|
+
causes fallback party allocation, which creates durable topology state; every
|
|
151
|
+
workflow also creates durable contracts. Set `SDK_EXAMPLE_PARTY` to an existing
|
|
152
|
+
party to rerun all four against that party and avoid fallback allocation. The
|
|
153
|
+
fixture DAR remains installed after a run.
|
|
154
|
+
|
|
155
|
+
Each program prints its actor plus the full participant version returned by the
|
|
156
|
+
authenticated status API, its parsed release core, and its selected path:
|
|
157
|
+
`Participant version:`, `Release core:`, and `Compatibility path:`. The current
|
|
158
|
+
implementation uses one common-code path for release cores 3.5.7 and 3.5.8. It
|
|
159
|
+
adds a version-specific behavioral difference only after live evidence proves
|
|
160
|
+
one; it does not infer compatibility from a container tag or endpoint.
|
|
161
|
+
|
|
162
|
+
- `example:workflow:atomic` first proves that an invalid choice is rejected,
|
|
163
|
+
then proves an atomic create-and-exercise by reading the created replacement
|
|
164
|
+
and its exact text.
|
|
165
|
+
- `example:workflow:retry` submits a caller-controlled command ID with a
|
|
166
|
+
deduplication duration, retries the exact same request, classifies the
|
|
167
|
+
duplicate outcome, and proves that exactly one matching contract is active.
|
|
168
|
+
- `example:workflow:resume` saves the ledger end before its post-offset create,
|
|
169
|
+
proves the intentionally idle stream timeout, then resumes exclusively after
|
|
170
|
+
that saved offset and rejects a pre-offset contract if it appears.
|
|
171
|
+
- `example:workflow:stale-contract` proves archive/replacement state and then
|
|
172
|
+
proves that exercising the archived contract is rejected.
|
|
173
|
+
|
|
174
|
+
Expected failures are accepted only through structured error classification:
|
|
175
|
+
gRPC status code, decoded status, operation, and the selected compatibility
|
|
176
|
+
path—not prose matching. The retry example uses one explicit command ID and
|
|
177
|
+
deduplication period for the exact same request; changing either value is a new
|
|
178
|
+
request and is not a retry proof. The resume example treats the saved offset as
|
|
179
|
+
exclusive, so its resumed stream must observe only updates after the saved
|
|
180
|
+
ledger end.
|
|
181
|
+
|
|
182
|
+
The workflow source and unit contracts were developed and live-tested against
|
|
183
|
+
authenticated Participant 3.5.7 and the isolated Participant 3.5.8. Both
|
|
184
|
+
final-tree matrices selected the same unchanged implementation and common
|
|
185
|
+
compatibility path. The normalized outcome comparison is identical: atomic
|
|
186
|
+
reports `invalidChoice` before its replacement proof, retry reports
|
|
187
|
+
`duplicateCommand` with one active contract, resume reports `idle-timeout` and
|
|
188
|
+
a post-offset update, and stale-contract reports `staleContract`.
|
|
189
|
+
|
|
190
|
+
The best multi-version path reads the authenticated full version, parses its
|
|
191
|
+
release core, and uses data-only structured compatibility for observed
|
|
192
|
+
outcomes. A behavioral difference is introduced only after live proof; it is
|
|
193
|
+
never inferred from a container tag, endpoint, or prose error message. For the
|
|
194
|
+
isolated 3.5.8 sidecar, use the SDK sidecar launcher's protected documented
|
|
195
|
+
credential refresh flow in a local child shell and refresh before expiry. Never
|
|
196
|
+
log its output or expose refreshed credentials beyond that child. Use the
|
|
197
|
+
documented `SDK_EXAMPLE_*` environment variables when running the workflow
|
|
198
|
+
commands.
|
|
199
|
+
|
|
200
|
+
By default, Ledger and Ledger Admin use `localhost:3901`; Participant Admin
|
|
201
|
+
uses `localhost:3902`. Override them with
|
|
202
|
+
`SDK_EXAMPLE_LEDGER_ENDPOINT`, `SDK_EXAMPLE_LEDGER_ADMIN_ENDPOINT`, and
|
|
203
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_ENDPOINT`. Use `SDK_EXAMPLE_BEARER_TOKEN` for a
|
|
204
|
+
shared bearer token, or set `SDK_EXAMPLE_LEDGER_BEARER_TOKEN`,
|
|
205
|
+
`SDK_EXAMPLE_LEDGER_ADMIN_BEARER_TOKEN`, and
|
|
206
|
+
`SDK_EXAMPLE_PARTICIPANT_ADMIN_BEARER_TOKEN` per surface. The examples also
|
|
207
|
+
accept `SDK_EXAMPLE_PARTY`, `SDK_EXAMPLE_USER_ID`, `SDK_EXAMPLE_SYNCHRONIZER`,
|
|
208
|
+
and `SDK_EXAMPLE_TIMEOUT_MS`; generated fallback party names use
|
|
209
|
+
`SDK_EXAMPLE_PARTY_PREFIX` when supplied. For TLS, set
|
|
210
|
+
`SDK_EXAMPLE_TLS_ROOT_CERTIFICATE` to a custom CA certificate path.
|
|
211
|
+
|
|
212
|
+
Some commands intentionally create durable localnet state: DAR upload installs
|
|
213
|
+
a package; create/exercise, query, and stream may allocate a fallback party and
|
|
214
|
+
create contracts; topology inspection may allocate a fallback party. User-rights
|
|
215
|
+
is read-only. These examples do not clean up durable state.
|
|
216
|
+
|
|
217
|
+
The uploaded asset is
|
|
218
|
+
`canton-explorer-debug-playground-0.1.0.dar`, the normal (not debug) Canton
|
|
219
|
+
Explorer Debug Playground DAR from
|
|
220
|
+
`/home/helena/dev/daml/canton-explorer/debug-playground/.daml/dist/canton-explorer-debug-playground-0.1.0.dar`.
|
|
221
|
+
Its Canton Explorer checkout commit is `750b28dd0ce4674e4368c12a6da1b5b5cbb00f88`,
|
|
222
|
+
its package-introduction commit is `abde077`, it is Apache-2.0 licensed, and
|
|
223
|
+
its SHA-256 is
|
|
224
|
+
`307cf7c52ac2770d1d1a2c5e1ec56a78ab7c70e7809c0cfb419abadb93cc6e29`.
|
|
225
|
+
|
|
226
|
+
The examples and their DAR are repository-only and excluded from the npm
|
|
227
|
+
tarball. The existing setup and decentralized-party examples were developed
|
|
228
|
+
and live-tested against Participant 3.5.7, then live-tested unchanged against
|
|
229
|
+
the isolated [Participant 3.5.8 sidecar](#optional-canton-358-participant-sidecar).
|
|
230
|
+
The workflow examples have completed 3.5.7 and 3.5.8 workflow matrices with
|
|
231
|
+
authenticated status evidence, the same unchanged implementation, and the
|
|
232
|
+
common compatibility path.
|
|
233
|
+
|
|
95
234
|
## Localnet launchers
|
|
96
235
|
|
|
97
236
|
The published package includes launchers for an existing CN Quickstart checkout.
|
|
@@ -133,13 +272,21 @@ Compose project, its Postgres container, and host ports `8901` (Ledger), `8902`
|
|
|
133
272
|
registered synchronizer via its Admin API, stores the exported connection
|
|
134
273
|
configuration in the sidecar runtime directory, and connects the sidecar with
|
|
135
274
|
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
|
-
|
|
275
|
+
at `.generated/participant-358/ledger-api-user.token`. When the connection is
|
|
276
|
+
healthy, use the protected child-shell credential flow below to make the
|
|
277
|
+
live-test and example endpoint/token variables available without logging them.
|
|
278
|
+
Canton 3.5.8 enforces this short lifetime for the unsafe development JWT.
|
|
138
279
|
`cn-quickstart` is strictly read-only: this launcher never writes to, starts,
|
|
139
280
|
or stops the normal Quickstart stack.
|
|
140
281
|
|
|
141
|
-
|
|
142
|
-
the
|
|
282
|
+
Refresh short-lived credentials before expiry without restarting or otherwise
|
|
283
|
+
touching the running containers. Use the launcher's protected documented
|
|
284
|
+
credential refresh flow only in a local child shell; do not log its output or
|
|
285
|
+
expose refreshed credentials beyond that child. The runtime credential file
|
|
286
|
+
remains protected with mode `0600`.
|
|
287
|
+
|
|
288
|
+
After the protected credential flow completes, run the example inside that same
|
|
289
|
+
short-lived credential-scoped child shell:
|
|
143
290
|
|
|
144
291
|
```bash
|
|
145
292
|
npm run example:party:decentralized
|
|
@@ -151,11 +298,14 @@ localnet differs:
|
|
|
151
298
|
|
|
152
299
|
```bash
|
|
153
300
|
PARTICIPANT_358_SOURCE_ADMIN_ENDPOINT=localhost:3902 \
|
|
154
|
-
PARTICIPANT_358_SOURCE_ADMIN_BEARER_TOKEN="$TOKEN" \
|
|
155
301
|
PARTICIPANT_358_NETWORK=quickstart \
|
|
156
302
|
canton-localnet-participant-358-start
|
|
157
303
|
```
|
|
158
304
|
|
|
305
|
+
Provide any required source-admin credential only through the protected
|
|
306
|
+
child-scoped credential mechanism described above; do not place credentials in
|
|
307
|
+
command lines or logs.
|
|
308
|
+
|
|
159
309
|
Use `PARTICIPANT_358_CANTON_IMAGE`, `PARTICIPANT_358_PROJECT_NAME`,
|
|
160
310
|
`PARTICIPANT_358_RUNTIME_DIR`, `PARTICIPANT_358_LEDGER_PORT`,
|
|
161
311
|
`PARTICIPANT_358_ADMIN_PORT`, and `PARTICIPANT_358_JSON_PORT` to make an
|
|
@@ -179,11 +329,12 @@ a self-signed certificate in `.generated/localnet-es256` at the package root. Se
|
|
|
179
329
|
use your own matching PEM private key and certificate.
|
|
180
330
|
|
|
181
331
|
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
|
-
|
|
332
|
+
`ledger-api-user.token` in that runtime directory and prints its path. In a
|
|
333
|
+
short-lived child shell, use a protected local credential mechanism to make the
|
|
334
|
+
token available without placing its value or a token-file read in a command
|
|
335
|
+
line or log. From within that same child shell, run the live SDK suite:
|
|
184
336
|
|
|
185
337
|
```bash
|
|
186
|
-
SDK_TEST_LEDGER_BEARER_TOKEN="$(cat .generated/localnet-es256/ledger-api-user.token)" \
|
|
187
338
|
npm run test:live
|
|
188
339
|
```
|
|
189
340
|
|
|
@@ -356,11 +507,11 @@ import {
|
|
|
356
507
|
BearerTokenAuthProvider,
|
|
357
508
|
CantonClient,
|
|
358
509
|
CantonClientOptions,
|
|
359
|
-
GetActiveContractsPageRequest,
|
|
360
510
|
HealthCheckRequest,
|
|
361
511
|
GetLedgerApiVersionRequest,
|
|
362
512
|
TransportKind,
|
|
363
513
|
} from "@distrohelena/canton-typescript-sdk";
|
|
514
|
+
import { ledgerApiV2 } from "@distrohelena/canton-typescript-sdk/protobuf";
|
|
364
515
|
|
|
365
516
|
const client = new CantonClient(
|
|
366
517
|
new CantonClientOptions({
|
|
@@ -393,14 +544,18 @@ const party = await client.partyManagementService.allocatePartyAsync(
|
|
|
393
544
|
}),
|
|
394
545
|
);
|
|
395
546
|
const contracts = await client.stateService.getActiveContractsPageAsync(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
547
|
+
ledgerApiV2.GetActiveContractsPageRequest.create({
|
|
548
|
+
eventFormat: {
|
|
549
|
+
filtersByParty: {
|
|
550
|
+
Alice: { cumulative: [] },
|
|
551
|
+
},
|
|
552
|
+
verbose: true,
|
|
553
|
+
},
|
|
399
554
|
}),
|
|
400
555
|
);
|
|
401
556
|
```
|
|
402
557
|
|
|
403
|
-
`stateService.getActiveContractsPageAsync(...)`
|
|
558
|
+
`stateService.getActiveContractsPageAsync(...)` accepts the generated Ledger API request on gRPC, including its `eventFormat`, `activeAtOffset`, `maxPageSize`, and `pageToken` fields. Build party, template, and interface filters in `eventFormat`. JSON does not implement this paginated RPC; use `getActiveContractsAsync(...)` for JSON streaming reads.
|
|
404
559
|
|
|
405
560
|
For interface views, do not use `contractService.getContractAsync(...)`. That contract lookup surface cannot return interface views; use `stateService` or `updateService` instead.
|
|
406
561
|
|
|
@@ -547,7 +702,7 @@ unsupported query features reject with `QueryCapabilityError`.
|
|
|
547
702
|
- `packageService.listVettedPackagesAsync(...)`: `grpc` only
|
|
548
703
|
- `commandService.submitAndWaitAsync(...)`: `json`, `grpc`
|
|
549
704
|
- `commandSubmissionService.submitAsync(...)`: reserved, currently unsupported
|
|
550
|
-
- `stateService.getActiveContractsPageAsync(...)`: `
|
|
705
|
+
- `stateService.getActiveContractsPageAsync(...)`: `grpc` only
|
|
551
706
|
- `stateService.getActiveContractsAsync(...)`: `json` only
|
|
552
707
|
- `updateService.getUpdatesAsync(...)`: `grpc` only
|
|
553
708
|
- `commandCompletionService`: placeholder, no methods yet
|
|
@@ -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;
|