@distrohelena/canton-typescript-sdk 0.1.35 → 0.1.37

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.
Files changed (102) hide show
  1. package/README.md +159 -51
  2. package/dist/cjs/core/types/requests/{submit-command-request.js → submit-commands-request.js} +10 -6
  3. package/dist/cjs/index.js +10 -8
  4. package/dist/cjs/query/canonical/in-memory-query-evaluator.js +291 -0
  5. package/dist/cjs/query/canonical/public-identity.js +41 -0
  6. package/dist/cjs/query/canonical/query-ast.js +2 -0
  7. package/dist/cjs/query/canonical/query-dataset.js +351 -0
  8. package/dist/cjs/query/canonical/query-normalizer.js +655 -0
  9. package/dist/cjs/query/canonical/query-schema.js +86 -0
  10. package/dist/cjs/query/canton-manager.js +14 -5
  11. package/dist/cjs/query/errors/query-snapshot-incomplete-error.js +19 -0
  12. package/dist/cjs/query/grpc/grpc-contract-cache.js +484 -0
  13. package/dist/cjs/query/grpc/grpc-package-relation-reader.js +218 -0
  14. package/dist/cjs/query/grpc/grpc-query-client.js +249 -0
  15. package/dist/cjs/query/grpc/grpc-query-snapshot-reader.js +238 -0
  16. package/dist/cjs/query/grpc/grpc-query-value-mapper.js +204 -0
  17. package/dist/cjs/query/grpc/grpc-relation-mapper.js +794 -0
  18. package/dist/cjs/query/pqs/pqs-query-client.js +151 -582
  19. package/dist/cjs/query/pqs/pqs-relational-sql-compiler.js +138 -95
  20. package/dist/cjs/query/pqs/pqs-result-shape.js +28 -0
  21. package/dist/cjs/query/pqs/pqs-schema-profile.js +49 -48
  22. package/dist/cjs/query/pqs/pqs-sql-compiler.js +343 -289
  23. package/dist/cjs/query/pqs/pqs-sql-syntax.js +10 -0
  24. package/dist/cjs/services/command/command-service-client.js +16 -3
  25. package/dist/cjs/services/commands/command-payload-builder.js +1 -1
  26. package/dist/cjs/services/commands/command-submission-pipeline.js +21 -6
  27. package/dist/cjs/services/state/state-service-client.js +56 -0
  28. package/dist/cjs/testing/runtime/declarative-action-executor.js +3 -3
  29. package/dist/cjs/transports/grpc/grpc-transport.js +2 -2
  30. package/dist/cjs/transports/grpc/mappers/commands-mapper.js +6 -6
  31. package/dist/cjs/transports/grpc/mappers/interactive-command-mapper.js +1 -1
  32. package/dist/cjs/transports/json/json-transport.js +1 -1
  33. package/dist/cjs/transports/json/mappers/commands-mapper.js +3 -3
  34. package/dist/core/transports/transport.interface.d.ts +4 -4
  35. package/dist/core/types/prepared-command-submission.d.ts +3 -3
  36. package/dist/core/types/requests/{submit-command-request.d.ts → submit-commands-request.d.ts} +8 -4
  37. package/dist/core/types/requests/{submit-command-request.js → submit-commands-request.js} +8 -4
  38. package/dist/index.d.ts +5 -2
  39. package/dist/index.js +2 -1
  40. package/dist/query/canonical/in-memory-query-evaluator.d.ts +22 -0
  41. package/dist/query/canonical/in-memory-query-evaluator.js +287 -0
  42. package/dist/query/canonical/public-identity.d.ts +14 -0
  43. package/dist/query/canonical/public-identity.js +35 -0
  44. package/dist/query/canonical/query-ast.d.ts +104 -0
  45. package/dist/query/canonical/query-ast.js +1 -0
  46. package/dist/query/canonical/query-dataset.d.ts +63 -0
  47. package/dist/query/canonical/query-dataset.js +343 -0
  48. package/dist/query/canonical/query-normalizer.d.ts +10 -0
  49. package/dist/query/canonical/query-normalizer.js +646 -0
  50. package/dist/query/canonical/query-schema.d.ts +25 -0
  51. package/dist/query/canonical/query-schema.js +83 -0
  52. package/dist/query/canton-manager.js +14 -5
  53. package/dist/query/errors/query-snapshot-incomplete-error.d.ts +14 -0
  54. package/dist/query/errors/query-snapshot-incomplete-error.js +15 -0
  55. package/dist/query/grpc/grpc-contract-cache.d.ts +27 -0
  56. package/dist/query/grpc/grpc-contract-cache.js +479 -0
  57. package/dist/query/grpc/grpc-package-relation-reader.d.ts +43 -0
  58. package/dist/query/grpc/grpc-package-relation-reader.js +213 -0
  59. package/dist/query/grpc/grpc-query-client.d.ts +42 -0
  60. package/dist/query/grpc/grpc-query-client.js +245 -0
  61. package/dist/query/grpc/grpc-query-snapshot-reader.d.ts +33 -0
  62. package/dist/query/grpc/grpc-query-snapshot-reader.js +233 -0
  63. package/dist/query/grpc/grpc-query-value-mapper.d.ts +15 -0
  64. package/dist/query/grpc/grpc-query-value-mapper.js +195 -0
  65. package/dist/query/grpc/grpc-relation-mapper.d.ts +67 -0
  66. package/dist/query/grpc/grpc-relation-mapper.js +789 -0
  67. package/dist/query/pqs/pqs-query-client.d.ts +10 -20
  68. package/dist/query/pqs/pqs-query-client.js +154 -585
  69. package/dist/query/pqs/pqs-relational-sql-compiler.d.ts +9 -17
  70. package/dist/query/pqs/pqs-relational-sql-compiler.js +136 -95
  71. package/dist/query/pqs/pqs-result-shape.d.ts +25 -0
  72. package/dist/query/pqs/pqs-result-shape.js +25 -0
  73. package/dist/query/pqs/pqs-schema-profile.js +49 -48
  74. package/dist/query/pqs/pqs-sql-compiler.d.ts +18 -3
  75. package/dist/query/pqs/pqs-sql-compiler.js +337 -288
  76. package/dist/query/pqs/pqs-sql-syntax.d.ts +2 -0
  77. package/dist/query/pqs/pqs-sql-syntax.js +6 -0
  78. package/dist/query/query-client.d.ts +15 -0
  79. package/dist/services/command/command-service-client.d.ts +9 -4
  80. package/dist/services/command/command-service-client.js +16 -3
  81. package/dist/services/command-submission/command-submission-service-client.d.ts +2 -2
  82. package/dist/services/commands/command-payload-builder.d.ts +2 -2
  83. package/dist/services/commands/command-payload-builder.js +1 -1
  84. package/dist/services/commands/command-submission-pipeline.d.ts +5 -4
  85. package/dist/services/commands/command-submission-pipeline.js +21 -6
  86. package/dist/services/state/state-service-client.d.ts +4 -0
  87. package/dist/services/state/state-service-client.js +56 -0
  88. package/dist/testing/runtime/declarative-action-executor.js +3 -3
  89. package/dist/transports/grpc/grpc-transport.d.ts +4 -4
  90. package/dist/transports/grpc/grpc-transport.js +3 -3
  91. package/dist/transports/grpc/mappers/commands-mapper.d.ts +3 -3
  92. package/dist/transports/grpc/mappers/commands-mapper.js +4 -4
  93. package/dist/transports/grpc/mappers/interactive-command-mapper.d.ts +3 -3
  94. package/dist/transports/grpc/mappers/interactive-command-mapper.js +1 -1
  95. package/dist/transports/json/json-transport.d.ts +2 -2
  96. package/dist/transports/json/json-transport.js +2 -2
  97. package/dist/transports/json/mappers/commands-mapper.d.ts +2 -2
  98. package/dist/transports/json/mappers/commands-mapper.js +2 -2
  99. package/package.json +8 -3
  100. package/dist/cjs/query/grpc/grpc-contract-query-client.js +0 -178
  101. package/dist/query/grpc/grpc-contract-query-client.d.ts +0 -33
  102. package/dist/query/grpc/grpc-contract-query-client.js +0 -174
@@ -0,0 +1,794 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapGrpcQueryRelationFragment = mapGrpcQueryRelationFragment;
4
+ exports.createGrpcQueryDataset = createGrpcQueryDataset;
5
+ exports.referencedGrpcPackageIds = referencedGrpcPackageIds;
6
+ const validation_error_js_1 = require("../../core/errors/validation-error.js");
7
+ const query_dataset_js_1 = require("../canonical/query-dataset.js");
8
+ const public_identity_js_1 = require("../canonical/public-identity.js");
9
+ const grpc_query_value_mapper_js_1 = require("./grpc-query-value-mapper.js");
10
+ /** Materializes ledger-effects transactions and optionally seeds still-active ACS contracts. */
11
+ function mapGrpcQueryRelationFragment(source, activeContracts = []) {
12
+ const transactions = [...source].sort((left, right) => compareOffset(left.offset, right.offset));
13
+ const activeEntries = activeContractEntries(activeContracts);
14
+ const seenOffsets = new Set();
15
+ const pending = [];
16
+ for (const transaction of transactions) {
17
+ validOffset(transaction.offset, "transaction offset");
18
+ validateTransaction(transaction);
19
+ if (seenOffsets.has(transaction.offset)) {
20
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate transaction offset ${transaction.offset}`);
21
+ }
22
+ seenOffsets.add(transaction.offset);
23
+ for (const event of transaction.events) {
24
+ pending.push(pendingEvent(transaction, event));
25
+ }
26
+ }
27
+ const eventIdentities = new Set();
28
+ for (const event of pending) {
29
+ if (eventIdentities.has(event.identity)) {
30
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate event ${eventId(event.event)}`);
31
+ }
32
+ eventIdentities.add(event.identity);
33
+ }
34
+ const registry = keyRegistry([
35
+ ...pending.map((item) => item.identity),
36
+ ...pending.flatMap((item) => identitiesFor(item.event)),
37
+ ...activeEntries.map((entry) => entry.event).flatMap(identitiesFor),
38
+ ]);
39
+ const transactionRows = transactions.map(mapTransaction);
40
+ const eventRows = pending
41
+ .slice()
42
+ .sort((left, right) => compareOffset(left.transaction.offset, right.transaction.offset) || nodeId(left.event) - nodeId(right.event))
43
+ .map((item) => ({ pk: (0, public_identity_js_1.canonicalPublicNumericIdentity)(eventId(item.event)), txIx: item.transaction.offset, eventId: eventId(item.event), type: item.kind }));
44
+ const eventPkByIdentity = new Map(pending.map((item) => [item.identity, (0, public_identity_js_1.canonicalPublicNumericIdentity)(eventId(item.event))]));
45
+ const contracts = new Map();
46
+ const creations = new Map();
47
+ const exerciseRows = [];
48
+ for (const item of pending.sort((left, right) => compareOffset(left.transaction.offset, right.transaction.offset) || nodeId(left.event) - nodeId(right.event))) {
49
+ if (item.kind === "created") {
50
+ addCreatedContract(contracts, creations, item.event, item.transaction.offset);
51
+ }
52
+ else {
53
+ const target = contracts.get(item.event.contractId);
54
+ if (target !== undefined && !target.active) {
55
+ throw new validation_error_js_1.ValidationError(`gRPC query exercise archives already archived contract ${item.event.contractId}`);
56
+ }
57
+ const template = requiredTemplate(item.event.templateId, "exercise template");
58
+ const owner = exerciseOwner(item.event);
59
+ exerciseRows.push({
60
+ tpePk: registry.get(exerciseIdentity(owner, item.event.choice, item.event.consuming)),
61
+ contractTpePk: registry.get(contractIdentity(target?.templateId ?? template)),
62
+ exerciseEventPk: eventPkByIdentity.get(item.identity),
63
+ exercisedAtIx: item.transaction.offset,
64
+ contractId: item.event.contractId,
65
+ argument: mapRequiredValue(item.event.choiceArgument, "exercise argument"),
66
+ result: item.event.exerciseResult === undefined ? null : (0, grpc_query_value_mapper_js_1.mapGrpcQueryValue)(item.event.exerciseResult),
67
+ redactionId: null,
68
+ packagePk: (0, public_identity_js_1.canonicalPublicNumericIdentity)(template.packageId),
69
+ controllers: immutableStrings(item.event.actingParties, "exercise acting parties", true),
70
+ lastDescendantNodeId: String(validNodeId(item.event.lastDescendantNodeId, "last descendant node id")),
71
+ witnesses: immutableStrings(item.event.witnessParties, "exercise witnesses", true),
72
+ });
73
+ if (item.event.consuming && target !== undefined) {
74
+ contracts.set(target.contractId, { ...target, archivedEventOffset: item.transaction.offset, archivedAt: timestamp(item.transaction.effectiveAt, "transaction effective time", true), active: false });
75
+ }
76
+ }
77
+ }
78
+ reconcileActiveContracts(contracts, creations, activeEntries);
79
+ const typeIdentities = [...new Map([...pending.map((item) => item.event), ...activeEntries.map((entry) => entry.event)].flatMap((event) => typeIdentityRows(event, registry).map((item) => [item.pk, item]))).values()].sort((left, right) => left.pk.localeCompare(right.pk));
80
+ const packageIdentities = [...new Set([...pending.flatMap((item) => packageIdsFor(item.event)), ...activeEntries.map((entry) => entry.event).flatMap(packageIdsFor)])]
81
+ .sort()
82
+ .map((id) => ({ pk: (0, public_identity_js_1.canonicalPublicNumericIdentity)(id), id }));
83
+ return (0, query_dataset_js_1.immutableQueryValue)({
84
+ contracts: [...contracts.values()].sort((left, right) => left.contractId.localeCompare(right.contractId)),
85
+ transactions: transactionRows,
86
+ events: eventRows,
87
+ exercises: exerciseRows.sort((left, right) => compareOffset(left.exercisedAtIx ?? "1", right.exercisedAtIx ?? "1") || (left.exerciseEventPk ?? "").localeCompare(right.exerciseEventPk ?? "") || left.contractId.localeCompare(right.contractId)),
88
+ typeIdentities,
89
+ packageIdentities,
90
+ creationIdentities: [...creations.values()].sort((left, right) => left.contractId.localeCompare(right.contractId)),
91
+ activeContractIdentities: activeEntries.map((entry) => ({ contractId: entry.event.contractId, synchronizerId: entry.synchronizerId, reassignmentCounter: entry.reassignmentCounter, activationOffset: entry.event.offset, activationNodeId: entry.event.nodeId }))
92
+ .sort((left, right) => left.contractId.localeCompare(right.contractId) || left.synchronizerId.localeCompare(right.synchronizerId)),
93
+ });
94
+ }
95
+ /**
96
+ * Combines the Task 5 ledger fragment with decoded LF package metadata into the
97
+ * complete immutable eight-relation snapshot. Private edge keys retain the
98
+ * creation template identity without exposing a synthetic field in contract rows.
99
+ */
100
+ function createGrpcQueryDataset(fragment, packages, endInclusive, instanceId) {
101
+ validSnapshotOffset(endInclusive);
102
+ if (instanceId.length === 0) {
103
+ throw new validation_error_js_1.ValidationError("gRPC query snapshot instance id is missing");
104
+ }
105
+ const normalizedPackages = normalizeGrpcPackageMetadata(packages);
106
+ const packageById = new Map();
107
+ for (const pkg of normalizedPackages) {
108
+ if (packageById.has(pkg.id)) {
109
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate package metadata ${pkg.id}`);
110
+ }
111
+ packageById.set(pkg.id, pkg);
112
+ }
113
+ const templates = normalizedPackages.flatMap((pkg) => pkg.templates.map((template) => ({ package: pkg, template })));
114
+ const templateByIdentity = new Map();
115
+ for (const entry of templates) {
116
+ const identity = templateIdentity(entry.package.id, entry.template.moduleName, entry.template.entityName);
117
+ if (templateByIdentity.has(identity)) {
118
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate DAML-LF template ${identity}`);
119
+ }
120
+ templateByIdentity.set(identity, entry);
121
+ }
122
+ const packagePublicKeys = new Map(normalizedPackages.map((pkg) => [pkg.id, (0, public_identity_js_1.canonicalPublicNumericIdentity)(pkg.id)]));
123
+ const contractTypePublicKeys = new Map(templates.map(({ package: pkg, template }) => [templateIdentity(pkg.id, template.moduleName, template.entityName), canonicalContractTypeKey(template.payloadType, template.templateFqn)]));
124
+ const exerciseTypePublicKeys = new Map(templates.flatMap(({ package: pkg, template }) => template.choices.map((choice) => [exerciseIdentity({ packageId: pkg.id, moduleName: template.moduleName, entityName: template.entityName }, choice.choice, choice.consuming), (0, public_identity_js_1.canonicalPublicNumericIdentity)(choice.choiceFqn)])));
125
+ const packageRows = [...normalizedPackages]
126
+ .sort((left, right) => left.id.localeCompare(right.id))
127
+ .map((pkg) => ({ pk: packagePublicKeys.get(pkg.id), name: pkg.name, version: pkg.version, id: pkg.id }));
128
+ const contractTypeRows = deduplicateCanonicalRows([...templates]
129
+ .sort(compareTemplateMetadata)
130
+ .map(({ package: pkg, template }) => ({
131
+ pk: contractTypePublicKeys.get(templateIdentity(pkg.id, template.moduleName, template.entityName)),
132
+ payloadType: template.payloadType,
133
+ aliases: template.aliases,
134
+ packageName: pkg.name,
135
+ moduleName: template.moduleName,
136
+ entityName: template.entityName,
137
+ templateFqn: template.templateFqn,
138
+ })));
139
+ const exerciseTypeRows = deduplicateCanonicalRows([...templates]
140
+ .flatMap(({ package: pkg, template }) => template.choices.map((choice) => ({ package: pkg, template, choice })))
141
+ .sort((left, right) => compareTemplateMetadata(left, right) || left.choice.choice.localeCompare(right.choice.choice) || Number(left.choice.consuming) - Number(right.choice.consuming))
142
+ .map(({ package: pkg, template, choice }) => ({
143
+ pk: exerciseTypePublicKeys.get(exerciseIdentity({ packageId: pkg.id, moduleName: template.moduleName, entityName: template.entityName }, choice.choice, choice.consuming)),
144
+ choice: choice.choice,
145
+ consuming: choice.consuming,
146
+ aliases: choice.aliases,
147
+ packageName: pkg.name,
148
+ moduleName: template.moduleName,
149
+ entityName: template.entityName,
150
+ templateFqn: template.templateFqn,
151
+ choiceFqn: choice.choiceFqn,
152
+ })));
153
+ const typeIdentityByOldPk = new Map(fragment.typeIdentities.map((identity) => [identity.pk, identity]));
154
+ const packageIdByOldPk = new Map(fragment.packageIdentities.map((identity) => [identity.pk, identity.id]));
155
+ const creationByContract = new Map(fragment.creationIdentities.map((identity) => [identity.contractId, identity]));
156
+ const exercises = fragment.exercises.map((exercise) => ({
157
+ ...exercise,
158
+ tpePk: canonicalExerciseTypeKeyForIdentity(typeIdentityByOldPk.get(exercise.tpePk), templateByIdentity, exerciseTypePublicKeys),
159
+ contractTpePk: canonicalContractTypeKeyForExercise(exercise.contractId, typeIdentityByOldPk.get(exercise.contractTpePk), creationByContract, templateByIdentity, contractTypePublicKeys),
160
+ packagePk: canonicalPackageKeyForId(packageIdByOldPk.get(exercise.packagePk), packagePublicKeys),
161
+ }));
162
+ const contractPrivateKeys = fragment.contracts.map((contract) => {
163
+ const creation = creationByContract.get(contract.contractId);
164
+ if (creation === undefined) {
165
+ throw new validation_error_js_1.ValidationError(`gRPC query creation identity is missing ${contract.contractId}`);
166
+ }
167
+ const key = contractTypePublicKeys.get(templateIdentity(creation.representativePackageId ?? creation.creationPackageId, creation.templateId.moduleName, creation.templateId.entityName));
168
+ if (key === undefined) {
169
+ throw new validation_error_js_1.ValidationError(`gRPC query representative contract type metadata is missing ${creation.contractId}`);
170
+ }
171
+ return [key];
172
+ });
173
+ const templatePrivateKeys = contractTypeRows.map((row) => [row.pk]);
174
+ const watermark = [{ singleton: true, ix: endInclusive, offset: endInclusive, instanceId }];
175
+ const transactionOffsets = new Set(fragment.transactions.map((transaction) => transaction.ix));
176
+ const activeContractIds = new Set(fragment.activeContractIdentities.map((identity) => identity.contractId));
177
+ const contractsWithoutCreatedTransaction = fragment.contracts.filter((contract) => !transactionOffsets.has(contract.createdEventOffset));
178
+ const createdTransactionIncomplete = contractsWithoutCreatedTransaction.length > 0 && contractsWithoutCreatedTransaction.every((contract) => activeContractIds.has(contract.contractId));
179
+ const eventPrivateKeys = fragment.events.map((event) => [event.eventId]);
180
+ const eventTransactionPrivateKeys = fragment.events.map((event) => [event.txIx]);
181
+ const transactionPrivateKeys = fragment.transactions.map((transaction) => [transaction.offset]);
182
+ const eventPrivateKeyByPk = new Map(fragment.events.map((event) => [event.pk, event.eventId]));
183
+ const packagePrivateKeys = packageRows.map((pkg) => [pkg.id]);
184
+ const packagePrivateKeyByPk = new Map(fragment.packageIdentities.map((pkg) => [pkg.pk, pkg.id]));
185
+ const contractTypePrivateKeys = contractTypeRows.map((row) => [row.pk]);
186
+ const exerciseTypePrivateKeys = exerciseTypeRows.map((row) => [row.pk]);
187
+ const exerciseEventPrivateKeys = fragment.exercises.map((exercise) => [exercise.exerciseEventPk === null ? null : eventPrivateKeyByPk.get(exercise.exerciseEventPk) ?? null]);
188
+ const exerciseTransactionPrivateKeys = exercises.map((exercise) => [exercise.exercisedAtIx]);
189
+ const exercisePackagePrivateKeys = fragment.exercises.map((exercise) => [packagePrivateKeyByPk.get(exercise.packagePk)]);
190
+ const exerciseContractTypePrivateKeys = exercises.map((exercise) => [exercise.contractTpePk]);
191
+ const exerciseTypePrivateKeysByExercise = exercises.map((exercise) => [exercise.tpePk]);
192
+ return (0, query_dataset_js_1.createQueryDataset)({
193
+ rows: {
194
+ contracts: fragment.contracts,
195
+ contractTypes: contractTypeRows,
196
+ events: fragment.events,
197
+ exercises: exercises,
198
+ exerciseTypes: exerciseTypeRows,
199
+ packages: packageRows,
200
+ transactions: fragment.transactions,
201
+ watermark: watermark,
202
+ },
203
+ uniqueKeys: {
204
+ contracts: [["contractId"]], contractTypes: [["pk"]], events: [["pk"]], exercises: [["tpePk", "contractTpePk", "exerciseEventPk", "contractId"]], exerciseTypes: [["pk"]], packages: [["pk"], ["id"]], transactions: [["ix"], ["offset"]], watermark: [["singleton"]],
205
+ },
206
+ edges: {
207
+ contracts: {
208
+ contractType: { privateKeys: { source: contractPrivateKeys, target: templatePrivateKeys } },
209
+ createdTransaction: { from: ["createdEventOffset"], to: ["ix"], ...(createdTransactionIncomplete ? { complete: false } : {}) },
210
+ archivedTransaction: { from: ["archivedEventOffset"], to: ["ix"] },
211
+ exercises: { from: ["contractId"], to: ["contractId"] },
212
+ },
213
+ contractTypes: {
214
+ contracts: { privateKeys: { source: templatePrivateKeys, target: contractPrivateKeys } },
215
+ exercises: { privateKeys: { source: contractTypePrivateKeys, target: exerciseContractTypePrivateKeys } },
216
+ },
217
+ events: { transaction: { privateKeys: { source: eventTransactionPrivateKeys, target: transactionPrivateKeys } }, exercises: { privateKeys: { source: eventPrivateKeys, target: exerciseEventPrivateKeys } } },
218
+ exercises: {
219
+ exerciseType: { privateKeys: { source: exerciseTypePrivateKeysByExercise, target: exerciseTypePrivateKeys } }, contractType: { privateKeys: { source: exerciseContractTypePrivateKeys, target: contractTypePrivateKeys } }, event: { privateKeys: { source: exerciseEventPrivateKeys, target: eventPrivateKeys } }, transaction: { privateKeys: { source: exerciseTransactionPrivateKeys, target: transactionPrivateKeys } }, package: { privateKeys: { source: exercisePackagePrivateKeys, target: packagePrivateKeys } }, contract: { from: ["contractId"], to: ["contractId"] },
220
+ },
221
+ exerciseTypes: { exercises: { privateKeys: { source: exerciseTypePrivateKeys, target: exerciseTypePrivateKeysByExercise } } },
222
+ packages: { exercises: { privateKeys: { source: packagePrivateKeys, target: exercisePackagePrivateKeys } } },
223
+ transactions: {
224
+ events: { privateKeys: { source: transactionPrivateKeys, target: eventTransactionPrivateKeys } }, createdContracts: { from: ["ix"], to: ["createdEventOffset"] }, archivedContracts: { from: ["ix"], to: ["archivedEventOffset"] }, exercises: { privateKeys: { source: transactionPrivateKeys, target: exerciseTransactionPrivateKeys } },
225
+ },
226
+ watermark: {},
227
+ },
228
+ });
229
+ }
230
+ /** Package payloads required for a contract/history relation plan, excluding creation-only provenance. */
231
+ function referencedGrpcPackageIds(fragment) {
232
+ const packageIdByPk = new Map(fragment.packageIdentities.map((identity) => [identity.pk, identity.id]));
233
+ const concreteExercisePackages = fragment.exercises.map((exercise) => {
234
+ const packageId = packageIdByPk.get(exercise.packagePk);
235
+ if (packageId === undefined) {
236
+ throw new validation_error_js_1.ValidationError("gRPC query relation package identity is missing");
237
+ }
238
+ return packageId;
239
+ });
240
+ return Object.freeze([...new Set([
241
+ ...fragment.creationIdentities.map((creation) => creation.representativePackageId ?? creation.creationPackageId),
242
+ ...concreteExercisePackages,
243
+ ...fragment.typeIdentities.filter((identity) => identity.choice !== undefined).map((identity) => identity.packageId),
244
+ ])].sort());
245
+ }
246
+ function compareTemplateMetadata(left, right) {
247
+ return left.package.id.localeCompare(right.package.id) || left.template.moduleName.localeCompare(right.template.moduleName) || left.template.entityName.localeCompare(right.template.entityName);
248
+ }
249
+ function normalizeGrpcPackageMetadata(packages) {
250
+ try {
251
+ return normalizeGrpcPackageMetadataUnsafe(packages);
252
+ }
253
+ catch (error) {
254
+ if (isValidationError(error)) {
255
+ throw error;
256
+ }
257
+ throw new validation_error_js_1.ValidationError("gRPC query package metadata is invalid");
258
+ }
259
+ }
260
+ function normalizeGrpcPackageMetadataUnsafe(packages) {
261
+ if (!Array.isArray(packages)) {
262
+ throw new validation_error_js_1.ValidationError("gRPC query package metadata is not an array");
263
+ }
264
+ const packageValues = Array.from(packages);
265
+ const packageIds = new Set();
266
+ const packageNameVersions = new Set();
267
+ const normalized = [];
268
+ for (const pkg of packageValues) {
269
+ if (pkg === null || typeof pkg !== "object") {
270
+ throw new validation_error_js_1.ValidationError("gRPC query package metadata is invalid");
271
+ }
272
+ const value = pkg;
273
+ const packageId = packageText(value.id, "id");
274
+ (0, grpc_query_value_mapper_js_1.validPackageIdString)(packageId, "package metadata id");
275
+ const packageName = packageText(value.name, "name");
276
+ const packageVersion = packageText(value.version, "version");
277
+ if (packageIds.has(packageId)) {
278
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate package metadata ${packageId}`);
279
+ }
280
+ packageIds.add(packageId);
281
+ const nameVersion = `${packageName}\u0000${packageVersion}`;
282
+ if (packageNameVersions.has(nameVersion)) {
283
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate package metadata ${packageName}@${packageVersion}`);
284
+ }
285
+ packageNameVersions.add(nameVersion);
286
+ const templatesValue = value.templates;
287
+ if (!Array.isArray(templatesValue)) {
288
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} templates are invalid`);
289
+ }
290
+ const templateValues = Array.from(templatesValue);
291
+ const templateIdentities = new Set();
292
+ const templates = Object.freeze(templateValues.map((template) => normalizePackageTemplate(packageId, packageName, template, templateIdentities)));
293
+ normalized.push(Object.freeze({ id: packageId, name: packageName, version: packageVersion, templates }));
294
+ }
295
+ return Object.freeze(normalized);
296
+ }
297
+ function normalizePackageTemplate(packageId, packageName, template, identities) {
298
+ if (template === null || typeof template !== "object") {
299
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} template is invalid`);
300
+ }
301
+ const value = template;
302
+ const moduleName = dottedPackageName(value.moduleName, `package ${packageId} template module`);
303
+ const entityName = dottedPackageName(value.entityName, `package ${packageId} template entity`);
304
+ const identity = templateIdentity(packageId, moduleName, entityName);
305
+ if (identities.has(identity)) {
306
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate DAML-LF template ${identity}`);
307
+ }
308
+ identities.add(identity);
309
+ const payloadType = value.payloadType;
310
+ if (payloadType !== "template" && payloadType !== "interface") {
311
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} template payload type is invalid`);
312
+ }
313
+ const aliases = exactAliases(value.aliases, [`${packageName}:${moduleName}:${entityName}`, `${moduleName}:${entityName}`, entityName], `package ${packageId} template`);
314
+ const templateFqn = exactText(value.templateFqn, `${packageName}:${moduleName}:${entityName}`, `package ${packageId} template FQN`);
315
+ const choicesValue = value.choices;
316
+ if (!Array.isArray(choicesValue)) {
317
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} template choices are invalid`);
318
+ }
319
+ const choiceValues = Array.from(choicesValue);
320
+ const choiceNames = new Set();
321
+ const choices = Object.freeze(choiceValues.map((choice) => normalizePackageChoice(packageId, packageName, moduleName, entityName, choice, choiceNames)));
322
+ return Object.freeze({ moduleName, entityName, payloadType, aliases, templateFqn, choices });
323
+ }
324
+ function normalizePackageChoice(packageId, packageName, moduleName, entityName, choice, choiceNames) {
325
+ if (choice === null || typeof choice !== "object") {
326
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} choice is invalid`);
327
+ }
328
+ const value = choice;
329
+ const choiceName = value.choice;
330
+ if (typeof choiceName !== "string") {
331
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} choice name is invalid`);
332
+ }
333
+ (0, grpc_query_value_mapper_js_1.validNameString)(choiceName, `package ${packageId} choice name`);
334
+ if (choiceNames.has(choiceName)) {
335
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate DAML-LF choice ${packageId}:${moduleName}:${entityName}:${choiceName}`);
336
+ }
337
+ choiceNames.add(choiceName);
338
+ const consuming = value.consuming;
339
+ if (typeof consuming !== "boolean") {
340
+ throw new validation_error_js_1.ValidationError(`gRPC query package ${packageId} choice consuming flag is invalid`);
341
+ }
342
+ const aliases = exactAliases(value.aliases, [
343
+ `${packageName}:${moduleName}:${entityName}:${choiceName}`,
344
+ `${moduleName}:${entityName}:${choiceName}`,
345
+ `${entityName}:${choiceName}`,
346
+ choiceName,
347
+ ], `package ${packageId} choice`);
348
+ const choiceFqn = exactText(value.choiceFqn, `${packageName}:${moduleName}:${entityName}:${choiceName}`, `package ${packageId} choice FQN`);
349
+ return Object.freeze({ choice: choiceName, consuming, aliases, choiceFqn });
350
+ }
351
+ function packageText(value, name) {
352
+ if (typeof value !== "string" || value.length === 0 || /[:\u0000-\u001F\u007F]/.test(value)) {
353
+ throw new validation_error_js_1.ValidationError(`gRPC query package metadata ${name} is invalid`);
354
+ }
355
+ return value;
356
+ }
357
+ function dottedPackageName(value, name) {
358
+ if (typeof value !== "string") {
359
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
360
+ }
361
+ return (0, grpc_query_value_mapper_js_1.validDottedNameString)(value, name);
362
+ }
363
+ function exactAliases(value, expected, name) {
364
+ if (!Array.isArray(value)) {
365
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} aliases are invalid`);
366
+ }
367
+ const aliases = Array.from(value);
368
+ if (aliases.length !== expected.length || aliases.some((alias, index) => alias !== expected[index])) {
369
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} aliases are invalid`);
370
+ }
371
+ return Object.freeze([...expected]);
372
+ }
373
+ function exactText(value, expected, name) {
374
+ if (value !== expected) {
375
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
376
+ }
377
+ return expected;
378
+ }
379
+ function isValidationError(error) {
380
+ try {
381
+ return error instanceof validation_error_js_1.ValidationError;
382
+ }
383
+ catch {
384
+ return false;
385
+ }
386
+ }
387
+ function templateIdentity(packageId, moduleName, entityName) {
388
+ return `${packageId}\u0000${moduleName}\u0000${entityName}`;
389
+ }
390
+ function templateKey(packageId, moduleName, entityName) {
391
+ return [packageId, moduleName, entityName];
392
+ }
393
+ function canonicalContractTypeKey(payloadType, templateFqn) {
394
+ return (0, public_identity_js_1.canonicalPublicNumericIdentityParts)([payloadType, templateFqn]);
395
+ }
396
+ function deduplicateCanonicalRows(rows) {
397
+ const byPk = new Map();
398
+ for (const row of rows) {
399
+ const existing = byPk.get(row.pk);
400
+ if (existing === undefined) {
401
+ byPk.set(row.pk, row);
402
+ }
403
+ else if (JSON.stringify(existing) !== JSON.stringify(row)) {
404
+ throw new validation_error_js_1.ValidationError(`gRPC query canonical public key ${row.pk} has conflicting metadata`);
405
+ }
406
+ }
407
+ return [...byPk.values()];
408
+ }
409
+ function canonicalExerciseTypeKeyForIdentity(identity, templates, keys) {
410
+ if (identity === undefined) {
411
+ throw new validation_error_js_1.ValidationError("gRPC query relation type identity is missing");
412
+ }
413
+ if (identity.choice === undefined) {
414
+ throw new validation_error_js_1.ValidationError("gRPC query relation exercise type identity is invalid");
415
+ }
416
+ const template = templates.get(templateIdentity(identity.templateId.packageId, identity.templateId.moduleName, identity.templateId.entityName));
417
+ const key = template === undefined ? undefined : keys.get(exerciseIdentity(identity.templateId, identity.choice, identity.consuming));
418
+ if (key === undefined) {
419
+ throw new validation_error_js_1.ValidationError("gRPC query relation type metadata is missing");
420
+ }
421
+ return key;
422
+ }
423
+ function canonicalContractTypeKeyForExercise(contractId, orphanIdentity, creations, templates, keys) {
424
+ const creation = creations.get(contractId);
425
+ if (creation === undefined) {
426
+ if (orphanIdentity === undefined || orphanIdentity.choice !== undefined) {
427
+ throw new validation_error_js_1.ValidationError("gRPC query orphan contract type identity is invalid");
428
+ }
429
+ const orphan = templates.get(templateIdentity(orphanIdentity.templateId.packageId, orphanIdentity.templateId.moduleName, orphanIdentity.templateId.entityName));
430
+ const key = orphan === undefined ? undefined : keys.get(templateIdentity(orphanIdentity.templateId.packageId, orphanIdentity.templateId.moduleName, orphanIdentity.templateId.entityName));
431
+ if (key === undefined) {
432
+ throw new validation_error_js_1.ValidationError("gRPC query orphan contract type metadata is missing");
433
+ }
434
+ return key;
435
+ }
436
+ const packageId = creation.representativePackageId ?? creation.creationPackageId;
437
+ const key = keys.get(templateIdentity(packageId, creation.templateId.moduleName, creation.templateId.entityName));
438
+ if (key === undefined) {
439
+ throw new validation_error_js_1.ValidationError(`gRPC query representative contract type metadata is missing ${packageId}:${creation.templateId.moduleName}:${creation.templateId.entityName}`);
440
+ }
441
+ return key;
442
+ }
443
+ function canonicalPackageKeyForId(packageId, keys) {
444
+ const key = packageId === undefined ? undefined : keys.get(packageId);
445
+ if (key === undefined) {
446
+ throw new validation_error_js_1.ValidationError("gRPC query relation package metadata is missing");
447
+ }
448
+ return key;
449
+ }
450
+ function pendingEvent(transaction, event) {
451
+ switch (event.event.oneofKind) {
452
+ case "created":
453
+ validatePending(transaction, event.event.created, "created");
454
+ return { transaction, event: event.event.created, kind: "created", identity: eventIdentity(event.event.created) };
455
+ case "exercised":
456
+ validatePending(transaction, event.event.exercised, "exercised");
457
+ return { transaction, event: event.event.exercised, kind: "exercised", identity: eventIdentity(event.event.exercised) };
458
+ default: throw new validation_error_js_1.ValidationError("gRPC query history contains a non-ledger-effects event");
459
+ }
460
+ }
461
+ function validatePending(transaction, event, kind) {
462
+ validOffset(event.offset, `${kind} event offset`);
463
+ validNodeId(event.nodeId, `${kind} node id`);
464
+ if (event.offset !== transaction.offset) {
465
+ throw new validation_error_js_1.ValidationError(`gRPC query ${kind} event offset differs from its transaction`);
466
+ }
467
+ (0, grpc_query_value_mapper_js_1.validLedgerString)(event.contractId, `${kind} event contract id`);
468
+ requiredTemplate(event.templateId, `${kind} event template`);
469
+ if (isExercised(event)) {
470
+ exerciseOwner(event);
471
+ if (event.packageName.length === 0) {
472
+ throw new validation_error_js_1.ValidationError("gRPC query exercise package name is missing");
473
+ }
474
+ else if (event.choiceArgument === undefined) {
475
+ throw new validation_error_js_1.ValidationError("gRPC query exercise argument is missing");
476
+ }
477
+ (0, grpc_query_value_mapper_js_1.validNameString)(event.choice, "exercise choice");
478
+ immutableStrings(event.actingParties, "exercise acting parties", true);
479
+ immutableStrings(event.witnessParties, "exercise witnesses", true);
480
+ validNodeId(event.lastDescendantNodeId, "last descendant node id");
481
+ if (event.lastDescendantNodeId < event.nodeId) {
482
+ throw new validation_error_js_1.ValidationError("gRPC query exercise last descendant node id precedes its node id");
483
+ }
484
+ }
485
+ else {
486
+ creationDescriptor(event, event.offset);
487
+ }
488
+ }
489
+ function addCreatedContract(contracts, creations, event, offset) {
490
+ const creation = creationDescriptor(event, offset);
491
+ if (contracts.has(event.contractId)) {
492
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate contract creation ${event.contractId}`);
493
+ }
494
+ contracts.set(event.contractId, {
495
+ contractId: creation.contractId,
496
+ templateId: creation.templateId,
497
+ packageId: creation.creationPackageId,
498
+ payload: creation.payload,
499
+ witnesses: creation.witnesses,
500
+ createdEventOffset: creation.offset,
501
+ createdAt: creation.createdAt,
502
+ archivedEventOffset: null,
503
+ archivedAt: null,
504
+ active: true,
505
+ });
506
+ creations.set(event.contractId, creation);
507
+ }
508
+ function mapTransaction(transaction) {
509
+ return {
510
+ ix: transaction.offset,
511
+ offset: transaction.offset,
512
+ transactionId: transaction.updateId,
513
+ effectiveAt: timestamp(transaction.effectiveAt, "transaction effective time", true),
514
+ workflowId: nullableString(transaction.workflowId),
515
+ domainId: null,
516
+ traceContext: transaction.traceContext === undefined ? null : transaction.traceContext,
517
+ externalTransactionHash: transaction.transactionHash === undefined
518
+ ? transaction.externalTransactionHash === undefined ? null : Uint8Array.from(transaction.externalTransactionHash)
519
+ : Uint8Array.from(transaction.transactionHash),
520
+ paidTrafficCost: transaction.paidTrafficCost === undefined ? null : signedInt64(transaction.paidTrafficCost, "paid traffic cost"),
521
+ };
522
+ }
523
+ function identitiesFor(event) {
524
+ const template = requiredTemplate(event.templateId, "event template");
525
+ return isExercised(event)
526
+ ? [eventIdentity(event), contractIdentity(template), ...packageIdsFor(event).map(packageIdentity), exerciseIdentity(exerciseOwner(event), event.choice, event.consuming)]
527
+ : [eventIdentity(event), contractIdentity(template), ...packageIdsFor(event).map(packageIdentity)];
528
+ }
529
+ function typeIdentityRows(event, registry) {
530
+ const template = requiredTemplate(event.templateId, "event template");
531
+ const contract = { pk: registry.get(contractIdentity(template)), templateId: copyTemplate(template), packageId: template.packageId };
532
+ if (!isExercised(event)) {
533
+ return [contract];
534
+ }
535
+ const owner = exerciseOwner(event);
536
+ return [contract, { pk: registry.get(exerciseIdentity(owner, event.choice, event.consuming)), templateId: copyTemplate(owner), packageId: owner.packageId, choice: event.choice, consuming: event.consuming }];
537
+ }
538
+ function activeContractEntries(responses) {
539
+ const entries = responses.map((response) => {
540
+ const contractEntry = response.contractEntry;
541
+ if (contractEntry.oneofKind !== "activeContract") {
542
+ throw new validation_error_js_1.ValidationError("gRPC query ACS contains incomplete assigned or unassigned contract data");
543
+ }
544
+ const active = contractEntry.activeContract;
545
+ const event = active.createdEvent;
546
+ if (event === undefined) {
547
+ throw new validation_error_js_1.ValidationError("gRPC query ACS contains incomplete assigned or unassigned contract data");
548
+ }
549
+ else if (active.synchronizerId.length === 0) {
550
+ throw new validation_error_js_1.ValidationError("gRPC query ACS active contract synchronizer id is missing");
551
+ }
552
+ creationDescriptor(event, event.offset);
553
+ return { event, synchronizerId: active.synchronizerId, reassignmentCounter: uint64(active.reassignmentCounter, "ACS active contract reassignment counter") };
554
+ });
555
+ const seen = new Set();
556
+ for (const entry of entries) {
557
+ const key = `${entry.event.contractId}\u0000${entry.synchronizerId}`;
558
+ if (seen.has(key)) {
559
+ throw new validation_error_js_1.ValidationError(`gRPC query has duplicate ACS activation for ${entry.event.contractId} on ${entry.synchronizerId}`);
560
+ }
561
+ seen.add(key);
562
+ }
563
+ return entries;
564
+ }
565
+ function reconcileActiveContracts(contracts, creations, entries) {
566
+ const grouped = new Map();
567
+ for (const entry of entries) {
568
+ let bucket = grouped.get(entry.event.contractId);
569
+ if (bucket === undefined) {
570
+ bucket = [];
571
+ grouped.set(entry.event.contractId, bucket);
572
+ }
573
+ bucket.push(entry);
574
+ }
575
+ for (const [contractId, group] of grouped) {
576
+ const descriptors = group.map((entry) => creationDescriptor(entry.event, entry.event.offset));
577
+ const facts = canonicalCreationFacts(descriptors[0]);
578
+ if (descriptors.some((descriptor) => canonicalCreationFacts(descriptor) !== facts)) {
579
+ throw new validation_error_js_1.ValidationError(`gRPC query ACS conflicts within activations for contract ${contractId}`);
580
+ }
581
+ const existing = contracts.get(contractId);
582
+ const historical = creations.get(contractId);
583
+ if (existing !== undefined && existing.active === false) {
584
+ throw new validation_error_js_1.ValidationError(`gRPC query ACS contains archived contract ${contractId}`);
585
+ }
586
+ else if (historical !== undefined && canonicalCreationFacts(historical) !== facts) {
587
+ throw new validation_error_js_1.ValidationError(`gRPC query ACS conflicts with history for contract ${contractId}`);
588
+ }
589
+ const witnesses = partyUnion([...(historical?.witnesses ?? []), ...descriptors.flatMap((descriptor) => descriptor.witnesses)], "created event witnesses", true);
590
+ if (existing === undefined) {
591
+ const representative = [...group].sort(compareActivation)[0];
592
+ addCreatedContract(contracts, creations, representative.event, representative.event.offset);
593
+ }
594
+ const creation = creations.get(contractId);
595
+ const updatedCreation = { ...creation, witnesses };
596
+ creations.set(contractId, updatedCreation);
597
+ contracts.set(contractId, { ...contracts.get(contractId), witnesses });
598
+ }
599
+ }
600
+ function compareActivation(left, right) {
601
+ const counter = BigInt(left.reassignmentCounter) - BigInt(right.reassignmentCounter);
602
+ return counter < 0n ? -1 : counter > 0n ? 1 : compareOffset(left.event.offset, right.event.offset) || left.synchronizerId.localeCompare(right.synchronizerId);
603
+ }
604
+ function creationDescriptor(event, offset) {
605
+ validOffset(offset, "created event offset");
606
+ validNodeId(event.nodeId, "created node id");
607
+ (0, grpc_query_value_mapper_js_1.validLedgerString)(event.contractId, "created event contract id");
608
+ if (event.packageName.length === 0) {
609
+ throw new validation_error_js_1.ValidationError("gRPC query created event package name is missing");
610
+ }
611
+ (0, grpc_query_value_mapper_js_1.validPackageIdString)(event.representativePackageId, "created event representative package id");
612
+ const template = requiredTemplate(event.templateId, "created event template");
613
+ if (event.createArguments === undefined) {
614
+ throw new validation_error_js_1.ValidationError("gRPC query created event has no create arguments");
615
+ }
616
+ const createdAt = requiredTimestamp(event.createdAt, "created event time");
617
+ immutableStrings(event.signatories, "created event signatories", true);
618
+ immutableStrings(event.observers, "created event observers");
619
+ return {
620
+ contractId: event.contractId,
621
+ offset,
622
+ templateId: copyTemplate(template),
623
+ creationPackageId: template.packageId,
624
+ representativePackageId: nullableString(event.representativePackageId),
625
+ payload: (0, grpc_query_value_mapper_js_1.mapGrpcQueryValue)({ sum: { oneofKind: "record", record: event.createArguments } }),
626
+ witnesses: immutableStrings(event.witnessParties, "created event witnesses", true),
627
+ createdAt,
628
+ };
629
+ }
630
+ function validateTransaction(transaction) {
631
+ if (transaction.events.length === 0) {
632
+ throw new validation_error_js_1.ValidationError("gRPC query transaction has no events");
633
+ }
634
+ else if (transaction.synchronizerId.length === 0) {
635
+ throw new validation_error_js_1.ValidationError("gRPC query transaction synchronizer id is missing");
636
+ }
637
+ (0, grpc_query_value_mapper_js_1.validLedgerString)(transaction.updateId, "transaction update id");
638
+ if (transaction.workflowId.length > 0) {
639
+ (0, grpc_query_value_mapper_js_1.validLedgerString)(transaction.workflowId, "transaction workflow id");
640
+ }
641
+ timestamp(transaction.effectiveAt, "transaction effective time", true);
642
+ timestamp(transaction.recordTime, "transaction record time", true);
643
+ }
644
+ function packageIdsFor(event) {
645
+ const template = requiredTemplate(event.templateId, "event template");
646
+ if (!isExercised(event)) {
647
+ return [template.packageId, ...event.representativePackageId.length === 0 ? [] : [event.representativePackageId]];
648
+ }
649
+ const owner = exerciseOwner(event);
650
+ return owner.packageId === template.packageId ? [template.packageId] : [template.packageId, owner.packageId];
651
+ }
652
+ function keyRegistry(identities) {
653
+ return new Map([...new Set(identities)].map((identity) => [identity, (0, public_identity_js_1.canonicalPublicNumericIdentity)(identity)]));
654
+ }
655
+ function contractIdentity(template) {
656
+ return `contract-type\u0000${template.packageId}\u0000${template.moduleName}\u0000${template.entityName}`;
657
+ }
658
+ function packageIdentity(id) {
659
+ return `package\u0000${id}`;
660
+ }
661
+ function exerciseIdentity(template, choice, consuming) {
662
+ return `exercise-type\u0000${template.packageId}\u0000${template.moduleName}\u0000${template.entityName}\u0000${choice}\u0000${consuming}`;
663
+ }
664
+ function eventIdentity(event) {
665
+ return `event\u0000${event.offset}\u0000${event.nodeId}`;
666
+ }
667
+ function eventId(event) {
668
+ return `${event.offset}:${event.nodeId}`;
669
+ }
670
+ function nodeId(event) {
671
+ return validNodeId(event.nodeId, "event node id");
672
+ }
673
+ function isExercised(event) {
674
+ return typeof event.choice === "string";
675
+ }
676
+ function requiredTemplate(template, name) {
677
+ if (template === undefined) {
678
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is missing`);
679
+ }
680
+ (0, grpc_query_value_mapper_js_1.validPackageIdString)(template.packageId, `${name} package id`);
681
+ (0, grpc_query_value_mapper_js_1.validDottedNameString)(template.moduleName, `${name} module name`);
682
+ (0, grpc_query_value_mapper_js_1.validDottedNameString)(template.entityName, `${name} entity name`);
683
+ return template;
684
+ }
685
+ function exerciseOwner(event) {
686
+ return event.interfaceId === undefined
687
+ ? requiredTemplate(event.templateId, "exercise template")
688
+ : requiredTemplate(event.interfaceId, "exercise interface");
689
+ }
690
+ function copyTemplate(template) {
691
+ return { packageId: template.packageId, moduleName: template.moduleName, entityName: template.entityName };
692
+ }
693
+ function mapRequiredValue(value, name) {
694
+ if (value === undefined) {
695
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is missing`);
696
+ }
697
+ return (0, grpc_query_value_mapper_js_1.mapGrpcQueryValue)(value);
698
+ }
699
+ function immutableStrings(value, name, required = false) {
700
+ if (required && value.length === 0) {
701
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is missing`);
702
+ }
703
+ return Object.freeze([...new Set(value.map(grpc_query_value_mapper_js_1.validPartyId))].sort());
704
+ }
705
+ function partyUnion(value, name, required = false) {
706
+ return immutableStrings(value, name, required);
707
+ }
708
+ function nullableString(value) {
709
+ return value.length === 0 ? null : value;
710
+ }
711
+ function validNodeId(value, name) {
712
+ if (!Number.isSafeInteger(value) || value < 0) {
713
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
714
+ }
715
+ return value;
716
+ }
717
+ function validOffset(value, name) {
718
+ if (!/^[1-9]\d*$/.test(value)) {
719
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
720
+ }
721
+ else if (BigInt(value) > 9223372036854775807n) {
722
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is outside the int64 range`);
723
+ }
724
+ return value;
725
+ }
726
+ function validSnapshotOffset(value) {
727
+ if (!/^(?:0|[1-9]\d*)$/.test(value)) {
728
+ throw new validation_error_js_1.ValidationError("gRPC query snapshot end offset is invalid");
729
+ }
730
+ else if (BigInt(value) > 9223372036854775807n) {
731
+ throw new validation_error_js_1.ValidationError("gRPC query snapshot end offset is outside the int64 range");
732
+ }
733
+ return value;
734
+ }
735
+ function signedInt64(value, name) {
736
+ if (!/^-?(?:0|[1-9]\d*)$/.test(value)) {
737
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
738
+ }
739
+ else if (BigInt(value) < -9223372036854775808n || BigInt(value) > 9223372036854775807n) {
740
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is outside the int64 range`);
741
+ }
742
+ return value;
743
+ }
744
+ function uint64(value, name) {
745
+ if (!/^(?:0|[1-9]\d*)$/.test(value)) {
746
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
747
+ }
748
+ else if (BigInt(value) > 18446744073709551615n) {
749
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is outside the uint64 range`);
750
+ }
751
+ return value;
752
+ }
753
+ function compareOffset(left, right) {
754
+ validOffset(left, "transaction offset");
755
+ validOffset(right, "transaction offset");
756
+ const first = BigInt(left);
757
+ const second = BigInt(right);
758
+ return first < second ? -1 : first > second ? 1 : 0;
759
+ }
760
+ function timestamp(value, name, required = false) {
761
+ if (value === undefined) {
762
+ if (required) {
763
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is missing`);
764
+ }
765
+ return null;
766
+ }
767
+ else if (!/^-?(?:0|[1-9]\d*)$/.test(value.seconds) || !Number.isInteger(value.nanos) || value.nanos < 0 || value.nanos > 999_999_999) {
768
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is invalid`);
769
+ }
770
+ const milliseconds = BigInt(value.seconds) * 1000n + BigInt(Math.trunc(value.nanos / 1_000_000));
771
+ if (milliseconds < -62135596800000n || milliseconds > 253402300799999n) {
772
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is outside the Ledger API range`);
773
+ }
774
+ return new Date(Number(milliseconds));
775
+ }
776
+ function requiredTimestamp(value, name) {
777
+ const mapped = timestamp(value, name, true);
778
+ if (mapped === null) {
779
+ throw new validation_error_js_1.ValidationError(`gRPC query ${name} is missing`);
780
+ }
781
+ return mapped;
782
+ }
783
+ function canonicalCreationFacts(value) {
784
+ return JSON.stringify({ contractId: value.contractId, templateId: value.templateId, creationPackageId: value.creationPackageId, representativePackageId: value.representativePackageId, createdAt: value.createdAt.toISOString(), payload: canonicalJson(value.payload) });
785
+ }
786
+ function canonicalJson(value) {
787
+ if (Array.isArray(value)) {
788
+ return value.map(canonicalJson);
789
+ }
790
+ else if (value !== null && typeof value === "object") {
791
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalJson(value[key])]));
792
+ }
793
+ return value;
794
+ }