@distrohelena/canton-typescript-sdk 0.1.5 → 0.1.7

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 (246) hide show
  1. package/README.md +333 -1
  2. package/dist/client/canton-client-options.d.ts +3 -0
  3. package/dist/client/canton-client-options.js +2 -0
  4. package/dist/client/service-registry.js +3 -2
  5. package/dist/core/errors/grpc-transport-error.d.ts +14 -0
  6. package/dist/core/errors/grpc-transport-error.js +76 -0
  7. package/dist/core/signing/command-signer.interface.d.ts +2 -0
  8. package/dist/core/transports/transport.interface.d.ts +2 -2
  9. package/dist/core/types/canton-hash-purpose.d.ts +2 -1
  10. package/dist/core/types/canton-hash-purpose.js +1 -0
  11. package/dist/core/types/daml-numeric.d.ts +6 -0
  12. package/dist/core/types/daml-numeric.js +14 -0
  13. package/dist/core/types/daml-party.d.ts +6 -0
  14. package/dist/core/types/daml-party.js +14 -0
  15. package/dist/core/types/disclosed-contract.d.ts +13 -0
  16. package/dist/core/types/disclosed-contract.js +15 -0
  17. package/dist/core/types/requests/create-decentralized-party-request.d.ts +41 -0
  18. package/dist/core/types/requests/create-decentralized-party-request.js +82 -0
  19. package/dist/core/types/requests/create-external-party-request.d.ts +42 -0
  20. package/dist/core/types/requests/create-external-party-request.js +47 -0
  21. package/dist/core/types/requests/finalize-decentralized-party-request.d.ts +39 -0
  22. package/dist/core/types/requests/finalize-decentralized-party-request.js +42 -0
  23. package/dist/core/types/requests/get-active-contracts-page-request.d.ts +15 -2
  24. package/dist/core/types/requests/get-active-contracts-page-request.js +4 -0
  25. package/dist/core/types/requests/submit-command-request.d.ts +5 -0
  26. package/dist/core/types/requests/submit-command-request.js +4 -0
  27. package/dist/core/types/topology/topology-signature-format.d.ts +2 -1
  28. package/dist/core/types/topology/topology-signature-format.js +1 -0
  29. package/dist/daml-lf/container/dar-archive-entry.d.ts +8 -0
  30. package/dist/daml-lf/container/dar-archive-entry.js +8 -0
  31. package/dist/daml-lf/container/dar-archive-loader.js +14 -0
  32. package/dist/daml-lf/container/dar-archive.d.ts +6 -0
  33. package/dist/daml-lf/container/dar-archive.js +4 -0
  34. package/dist/daml-lf/container/dar-source-bundle-loader.d.ts +5 -0
  35. package/dist/daml-lf/container/dar-source-bundle-loader.js +33 -0
  36. package/dist/daml-lf/container/dar-source-bundle.d.ts +45 -0
  37. package/dist/daml-lf/container/dar-source-bundle.js +11 -0
  38. package/dist/daml-lf/container/dar-source-file-entry.d.ts +8 -0
  39. package/dist/daml-lf/container/dar-source-file-entry.js +8 -0
  40. package/dist/daml-lf/daml-lf-compilation.d.ts +12 -0
  41. package/dist/daml-lf/daml-lf-compilation.js +35 -0
  42. package/dist/daml-lf/index.d.ts +11 -0
  43. package/dist/daml-lf/index.js +10 -0
  44. package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.d.ts +43 -0
  45. package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.js +933 -0
  46. package/dist/daml-lf/interpreter/daml-lf-evaluator.d.ts +95 -0
  47. package/dist/daml-lf/interpreter/daml-lf-evaluator.js +1131 -0
  48. package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.d.ts +3 -0
  49. package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.js +6 -1
  50. package/dist/daml-lf/interpreter/daml-lf-lexical-scope.d.ts +13 -0
  51. package/dist/daml-lf/interpreter/daml-lf-lexical-scope.js +46 -0
  52. package/dist/daml-lf/interpreter/daml-lf-runtime-frame.d.ts +16 -0
  53. package/dist/daml-lf/interpreter/daml-lf-runtime-frame.js +15 -0
  54. package/dist/daml-lf/interpreter/daml-lf-runtime-value.d.ts +21 -0
  55. package/dist/daml-lf/interpreter/daml-lf-runtime-value.js +4 -1
  56. package/dist/daml-lf/interpreter/daml-lf-step-kind.d.ts +7 -0
  57. package/dist/daml-lf/interpreter/daml-lf-step-kind.js +8 -0
  58. package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.d.ts +30 -0
  59. package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.js +1 -0
  60. package/dist/daml-lf/model/daml-lf-builtin-type.d.ts +3 -0
  61. package/dist/daml-lf/model/daml-lf-builtin-type.js +3 -0
  62. package/dist/daml-lf/model/daml-lf-choice.d.ts +5 -0
  63. package/dist/daml-lf/model/daml-lf-choice.js +4 -0
  64. package/dist/daml-lf/model/daml-lf-expression-path.d.ts +2 -0
  65. package/dist/daml-lf/model/daml-lf-expression-path.js +81 -0
  66. package/dist/daml-lf/model/daml-lf-expression.d.ts +146 -0
  67. package/dist/daml-lf/model/daml-lf-expression.js +71 -0
  68. package/dist/daml-lf/model/daml-lf-template.d.ts +2 -0
  69. package/dist/daml-lf/model/daml-lf-template.js +2 -0
  70. package/dist/daml-lf/model/daml-lf-type.d.ts +2 -0
  71. package/dist/daml-lf/model/daml-lf-type.js +4 -0
  72. package/dist/daml-lf/model/lf-2-model-mapper.d.ts +5 -0
  73. package/dist/daml-lf/model/lf-2-model-mapper.js +445 -12
  74. package/dist/debugger/errors/replay-determinism.exception.d.ts +3 -0
  75. package/dist/debugger/errors/replay-determinism.exception.js +3 -0
  76. package/dist/debugger/errors/replay-missing-package.exception.d.ts +3 -0
  77. package/dist/debugger/errors/replay-missing-package.exception.js +3 -0
  78. package/dist/debugger/errors/replay-missing-source.exception.d.ts +3 -0
  79. package/dist/debugger/errors/replay-missing-source.exception.js +3 -0
  80. package/dist/debugger/errors/replay-source-map.exception.d.ts +3 -0
  81. package/dist/debugger/errors/replay-source-map.exception.js +3 -0
  82. package/dist/debugger/errors/replay-state-hydration.exception.d.ts +3 -0
  83. package/dist/debugger/errors/replay-state-hydration.exception.js +3 -0
  84. package/dist/debugger/errors/replay-unsupported-lf-construct.exception.d.ts +3 -0
  85. package/dist/debugger/errors/replay-unsupported-lf-construct.exception.js +3 -0
  86. package/dist/debugger/errors/replay-unsupported-update.exception.d.ts +3 -0
  87. package/dist/debugger/errors/replay-unsupported-update.exception.js +3 -0
  88. package/dist/debugger/index.d.ts +31 -0
  89. package/dist/debugger/index.js +31 -0
  90. package/dist/debugger/ledger-replay-debugger-client.d.ts +31 -0
  91. package/dist/debugger/ledger-replay-debugger-client.js +53 -0
  92. package/dist/debugger/replay/ledger-replay-environment-builder.d.ts +95 -0
  93. package/dist/debugger/replay/ledger-replay-environment-builder.js +249 -0
  94. package/dist/debugger/replay/ledger-replay-session-loader.d.ts +78 -0
  95. package/dist/debugger/replay/ledger-replay-session-loader.js +565 -0
  96. package/dist/debugger/replay/replay-artifact-resolver.d.ts +30 -0
  97. package/dist/debugger/replay/replay-artifact-resolver.js +210 -0
  98. package/dist/debugger/replay/replay-determinism-validator.d.ts +12 -0
  99. package/dist/debugger/replay/replay-determinism-validator.js +161 -0
  100. package/dist/debugger/replay/replay-entrypoint-definition-resolver.d.ts +40 -0
  101. package/dist/debugger/replay/replay-entrypoint-definition-resolver.js +337 -0
  102. package/dist/debugger/replay/replay-entrypoint.d.ts +22 -0
  103. package/dist/debugger/replay/replay-entrypoint.js +14 -0
  104. package/dist/debugger/replay/replay-ledger-value-normalizer.d.ts +7 -0
  105. package/dist/debugger/replay/replay-ledger-value-normalizer.js +194 -0
  106. package/dist/debugger/replay/replay-update-loader.d.ts +24 -0
  107. package/dist/debugger/replay/replay-update-loader.js +94 -0
  108. package/dist/debugger/replay/replay-update-visibility-validator.d.ts +19 -0
  109. package/dist/debugger/replay/replay-update-visibility-validator.js +19 -0
  110. package/dist/debugger/session/in-memory-replay-session-store.d.ts +27 -0
  111. package/dist/debugger/session/in-memory-replay-session-store.js +109 -0
  112. package/dist/debugger/session/replay-phase.d.ts +7 -0
  113. package/dist/debugger/session/replay-phase.js +8 -0
  114. package/dist/debugger/session/replay-scope.d.ts +10 -0
  115. package/dist/debugger/session/replay-scope.js +10 -0
  116. package/dist/debugger/session/replay-session-metadata.d.ts +10 -0
  117. package/dist/debugger/session/replay-session-metadata.js +10 -0
  118. package/dist/debugger/session/replay-session-request.d.ts +6 -0
  119. package/dist/debugger/session/replay-session-request.js +10 -0
  120. package/dist/debugger/session/replay-session.d.ts +12 -0
  121. package/dist/debugger/session/replay-session.js +10 -0
  122. package/dist/debugger/session/replay-source-location.d.ts +17 -0
  123. package/dist/debugger/session/replay-source-location.js +16 -0
  124. package/dist/debugger/session/replay-stack-frame.d.ts +8 -0
  125. package/dist/debugger/session/replay-stack-frame.js +8 -0
  126. package/dist/debugger/session/replay-state-delta.d.ts +29 -0
  127. package/dist/debugger/session/replay-state-delta.js +24 -0
  128. package/dist/debugger/session/replay-step-advance-result.d.ts +24 -0
  129. package/dist/debugger/session/replay-step-advance-result.js +16 -0
  130. package/dist/debugger/session/replay-step.d.ts +30 -0
  131. package/dist/debugger/session/replay-step.js +24 -0
  132. package/dist/debugger/session/replay-value-preview.d.ts +8 -0
  133. package/dist/debugger/session/replay-value-preview.js +15 -0
  134. package/dist/debugger/source/daml-source-mapper.d.ts +12 -0
  135. package/dist/debugger/source/daml-source-mapper.js +21 -0
  136. package/dist/debugger/source/dar-source-map-metadata.d.ts +26 -0
  137. package/dist/debugger/source/dar-source-map-metadata.js +10 -0
  138. package/dist/debugger/source/source-coverage-validator.d.ts +8 -0
  139. package/dist/debugger/source/source-coverage-validator.js +16 -0
  140. package/dist/debugger/source/source-indexed-compilation.d.ts +45 -0
  141. package/dist/debugger/source/source-indexed-compilation.js +110 -0
  142. package/dist/debugger/source/source-mapping-precision.d.ts +5 -0
  143. package/dist/debugger/source/source-mapping-precision.js +4 -0
  144. package/dist/index.d.ts +21 -0
  145. package/dist/index.js +13 -0
  146. package/dist/query/cache/memory-query-cache.d.ts +9 -0
  147. package/dist/query/cache/memory-query-cache.js +24 -0
  148. package/dist/query/cache/query-cache-store.d.ts +5 -0
  149. package/dist/query/cache/query-cache-store.js +1 -0
  150. package/dist/query/canton-manager-options.d.ts +17 -0
  151. package/dist/query/canton-manager-options.js +1 -0
  152. package/dist/query/canton-manager.d.ts +11 -0
  153. package/dist/query/canton-manager.js +42 -0
  154. package/dist/query/errors/pqs-query-error.d.ts +10 -0
  155. package/dist/query/errors/pqs-query-error.js +11 -0
  156. package/dist/query/errors/pqs-schema-profile-error.d.ts +3 -0
  157. package/dist/query/errors/pqs-schema-profile-error.js +3 -0
  158. package/dist/query/errors/query-capability-error.d.ts +7 -0
  159. package/dist/query/errors/query-capability-error.js +10 -0
  160. package/dist/query/grpc/grpc-contract-query-client.d.ts +32 -0
  161. package/dist/query/grpc/grpc-contract-query-client.js +126 -0
  162. package/dist/query/model-types.d.ts +258 -0
  163. package/dist/query/model-types.js +14 -0
  164. package/dist/query/pqs/pqs-pool.d.ts +13 -0
  165. package/dist/query/pqs/pqs-pool.js +18 -0
  166. package/dist/query/pqs/pqs-query-client.d.ts +49 -0
  167. package/dist/query/pqs/pqs-query-client.js +324 -0
  168. package/dist/query/pqs/pqs-schema-profile.d.ts +25 -0
  169. package/dist/query/pqs/pqs-schema-profile.js +120 -0
  170. package/dist/query/pqs/pqs-sql-compiler.d.ts +7 -0
  171. package/dist/query/pqs/pqs-sql-compiler.js +132 -0
  172. package/dist/query/pqs/read-only-sql.d.ts +1 -0
  173. package/dist/query/pqs/read-only-sql.js +35 -0
  174. package/dist/query/query-client.d.ts +61 -0
  175. package/dist/query/query-client.js +1 -0
  176. package/dist/query/query-source.d.ts +4 -0
  177. package/dist/query/query-source.js +5 -0
  178. package/dist/services/command/command-service-client.d.ts +2 -2
  179. package/dist/services/commands/command-submission-pipeline.d.ts +2 -2
  180. package/dist/services/party-management/decentralized-party-lifecycle.d.ts +6 -0
  181. package/dist/services/party-management/decentralized-party-lifecycle.js +82 -0
  182. package/dist/services/party-management/party-management-service-client.d.ts +16 -1
  183. package/dist/services/party-management/party-management-service-client.js +142 -1
  184. package/dist/services/topology-manager-write/topology-signed-transaction-assembler.js +4 -0
  185. package/dist/testing/campaign/campaign-artifact.d.ts +20 -0
  186. package/dist/testing/campaign/campaign-artifact.js +147 -0
  187. package/dist/testing/campaign/campaign-definition.d.ts +9 -0
  188. package/dist/testing/campaign/campaign-definition.js +78 -0
  189. package/dist/testing/campaign/campaign-metrics.d.ts +32 -0
  190. package/dist/testing/campaign/campaign-metrics.js +26 -0
  191. package/dist/testing/campaign/campaign-model.d.ts +11 -0
  192. package/dist/testing/campaign/campaign-model.js +21 -0
  193. package/dist/testing/campaign/campaign-runner.d.ts +99 -0
  194. package/dist/testing/campaign/campaign-runner.js +194 -0
  195. package/dist/testing/campaign/campaign-scheduler.d.ts +40 -0
  196. package/dist/testing/campaign/campaign-scheduler.js +75 -0
  197. package/dist/testing/campaign/campaign-types.d.ts +52 -0
  198. package/dist/testing/campaign/campaign-types.js +11 -0
  199. package/dist/testing/daml/daml-action-arbitrary.d.ts +13 -0
  200. package/dist/testing/daml/daml-action-arbitrary.js +24 -0
  201. package/dist/testing/daml/daml-choice-action-arbitrary.d.ts +18 -0
  202. package/dist/testing/daml/daml-choice-action-arbitrary.js +27 -0
  203. package/dist/testing/daml/daml-create-action-arbitrary.d.ts +19 -0
  204. package/dist/testing/daml/daml-create-action-arbitrary.js +34 -0
  205. package/dist/testing/daml/daml-testing-catalog.d.ts +38 -0
  206. package/dist/testing/daml/daml-testing-catalog.js +40 -0
  207. package/dist/testing/daml/daml-value-arbitrary.d.ts +8 -0
  208. package/dist/testing/daml/daml-value-arbitrary.js +43 -0
  209. package/dist/testing/daml/declarative-campaign-arbitrary.d.ts +15 -0
  210. package/dist/testing/daml/declarative-campaign-arbitrary.js +30 -0
  211. package/dist/testing/errors/invariant-campaign-failure.d.ts +24 -0
  212. package/dist/testing/errors/invariant-campaign-failure.js +37 -0
  213. package/dist/testing/errors/testing-configuration-error.d.ts +3 -0
  214. package/dist/testing/errors/testing-configuration-error.js +6 -0
  215. package/dist/testing/handlers/handler.d.ts +19 -0
  216. package/dist/testing/handlers/handler.js +31 -0
  217. package/dist/testing/index.d.ts +22 -0
  218. package/dist/testing/index.js +22 -0
  219. package/dist/testing/runtime/campaign-isolation.d.ts +14 -0
  220. package/dist/testing/runtime/campaign-isolation.js +23 -0
  221. package/dist/testing/runtime/canton-test-runtime.d.ts +58 -0
  222. package/dist/testing/runtime/canton-test-runtime.js +138 -0
  223. package/dist/testing/runtime/declarative-action-executor.d.ts +16 -0
  224. package/dist/testing/runtime/declarative-action-executor.js +41 -0
  225. package/dist/testing/targets/target.d.ts +49 -0
  226. package/dist/testing/targets/target.js +121 -0
  227. package/dist/transports/grpc/grpc-channel-factory.js +31 -1
  228. package/dist/transports/grpc/grpc-transport.d.ts +2 -2
  229. package/dist/transports/grpc/grpc-transport.js +11 -8
  230. package/dist/transports/grpc/mappers/commands-mapper.js +23 -2
  231. package/dist/transports/grpc/mappers/contracts-mapper.d.ts +3 -1
  232. package/dist/transports/grpc/mappers/contracts-mapper.js +16 -3
  233. package/dist/transports/grpc/mappers/interactive-command-mapper.d.ts +4 -1
  234. package/dist/transports/grpc/mappers/interactive-command-mapper.js +3 -8
  235. package/dist/transports/grpc/mappers/topology-manager-write-mapper.js +59 -1
  236. package/dist/transports/json/mappers/commands-mapper.js +20 -6
  237. package/node/.generated/start-local/additional-config.extra-participants.conf +37 -0
  238. package/node/.generated/start-local/additional-config.extra-validators.conf +35 -0
  239. package/node/.generated/start-local/compose-extra-participants.yaml +147 -0
  240. package/node/.generated/start-local/extra-participants.env +30 -0
  241. package/node/es256-jwt.mjs +177 -0
  242. package/node/start-local.sh +886 -0
  243. package/node/stop-local.sh +200 -0
  244. package/node/test-start-local.sh +354 -0
  245. package/node/test-stop-local.sh +112 -0
  246. package/package.json +21 -2
@@ -0,0 +1,138 @@
1
+ import { TestingConfigurationError } from "../errors/testing-configuration-error.js";
2
+ export function createCantonTestRuntime(init) {
3
+ for (const [name, actor] of Object.entries(init.actors)) {
4
+ if (init.participants[actor.participant] === undefined) {
5
+ throw new TestingConfigurationError(`Canton test actor '${name}' references unknown participant '${actor.participant}'.`);
6
+ }
7
+ }
8
+ const actors = Object.freeze({ ...init.actors });
9
+ const participants = Object.freeze({ ...init.participants });
10
+ const resolveRoute = (actorName) => {
11
+ const actor = actors[actorName];
12
+ if (actor === undefined) {
13
+ throw new TestingConfigurationError(`Canton test runtime has no actor '${actorName}'.`);
14
+ }
15
+ return Object.freeze({
16
+ actor: actorName,
17
+ participant: actor.participant,
18
+ party: actor.party,
19
+ actAs: Object.freeze([...(actor.actAs ?? [actor.party])]),
20
+ readAs: Object.freeze([...(actor.readAs ?? [])]),
21
+ });
22
+ };
23
+ return Object.freeze({
24
+ actors,
25
+ participants,
26
+ isolation: init.isolation,
27
+ async readLedgerEndAsync(participantName) {
28
+ const participant = participants[participantName];
29
+ const stateService = readObjectProperty(participant, "stateService");
30
+ const getLedgerEndAsync = readFunctionProperty(stateService, "getLedgerEndAsync");
31
+ if (getLedgerEndAsync === undefined) {
32
+ throw new TestingConfigurationError(`Canton test participant '${participantName}' has no stateService.getLedgerEndAsync method.`);
33
+ }
34
+ const response = await getLedgerEndAsync.call(stateService);
35
+ const offset = readStringProperty(response, "offset");
36
+ if (offset === undefined) {
37
+ throw new TestingConfigurationError(`Canton test participant '${participantName}' returned no ledger end offset.`);
38
+ }
39
+ return offset;
40
+ },
41
+ resolveRoute,
42
+ async submitAndWaitAsync(actorName, request) {
43
+ const route = resolveRoute(actorName);
44
+ const participant = participants[route.participant];
45
+ const commandService = readObjectProperty(participant, "commandService");
46
+ const submitAndWaitAsync = readFunctionProperty(commandService, "submitAndWaitAsync");
47
+ if (submitAndWaitAsync === undefined) {
48
+ throw new TestingConfigurationError(`Canton test participant '${route.participant}' has no commandService.submitAndWaitAsync method.`);
49
+ }
50
+ try {
51
+ return classifyCantonCommandOutcome({
52
+ response: await submitAndWaitAsync.call(commandService, request),
53
+ });
54
+ }
55
+ catch (error) {
56
+ return classifyCantonCommandOutcome({ error });
57
+ }
58
+ },
59
+ });
60
+ }
61
+ export function classifyCantonCommandOutcome(input) {
62
+ if (input.error === undefined) {
63
+ const transactionId = readStringProperty(input.response, "transactionId");
64
+ const commandId = readStringProperty(input.response, "commandId");
65
+ return {
66
+ kind: "accepted",
67
+ ...(transactionId === undefined ? {} : { transactionId }),
68
+ ...(commandId === undefined ? {} : { commandId }),
69
+ };
70
+ }
71
+ const statusCode = readNumberProperty(input.error, "code");
72
+ const details = readStringProperty(input.error, "details") ?? "Unknown command failure.";
73
+ if ((statusCode === 9 && details.startsWith("DAML_INTERPRETATION_ERROR("))
74
+ || (statusCode === 3 && details.startsWith("DAML_AUTHORIZATION_ERROR("))) {
75
+ return { kind: "protocol-revert", statusCode, details };
76
+ }
77
+ else if (statusCode === 14 || statusCode === 13) {
78
+ return { kind: "transport-error", statusCode, details };
79
+ }
80
+ else if (statusCode === 4) {
81
+ return { kind: "timeout", statusCode, details };
82
+ }
83
+ return { kind: "unknown-commit-outcome", statusCode, details };
84
+ }
85
+ /** Converts the runtime's transport-safe outcome into the campaign metric union. */
86
+ export function toCampaignMetricOutcome(outcome) {
87
+ if (outcome.kind !== "accepted") {
88
+ return {
89
+ kind: outcome.kind,
90
+ reason: outcome.details,
91
+ };
92
+ }
93
+ const updateId = outcome.transactionId ?? outcome.commandId;
94
+ return updateId === undefined
95
+ ? {
96
+ kind: "malformed-response",
97
+ reason: "Canton command response has no transaction or command ID.",
98
+ }
99
+ : { kind: "accepted", updateId };
100
+ }
101
+ export async function pollUntilAsync(init) {
102
+ const deadline = Date.now() + init.timeoutMs;
103
+ while (true) {
104
+ const value = await init.readAsync();
105
+ if (init.isReady(value)) {
106
+ return value;
107
+ }
108
+ else if (Date.now() >= deadline) {
109
+ throw new Error("Canton test runtime polling timed out.");
110
+ }
111
+ await new Promise((resolveDelay) => {
112
+ setTimeout(resolveDelay, init.intervalMs);
113
+ });
114
+ }
115
+ }
116
+ function readNumberProperty(value, key) {
117
+ const candidate = value;
118
+ const property = candidate?.[key];
119
+ return typeof property === "number" ? property : undefined;
120
+ }
121
+ function readObjectProperty(value, key) {
122
+ const candidate = value;
123
+ const property = candidate?.[key];
124
+ return property !== null && typeof property === "object"
125
+ ? property
126
+ : undefined;
127
+ }
128
+ function readFunctionProperty(value, key) {
129
+ const property = value?.[key];
130
+ return typeof property === "function"
131
+ ? property
132
+ : undefined;
133
+ }
134
+ function readStringProperty(value, key) {
135
+ const candidate = value;
136
+ const property = candidate?.[key];
137
+ return typeof property === "string" ? property : undefined;
138
+ }
@@ -0,0 +1,16 @@
1
+ import { DeclarativeAction } from "../daml/daml-action-arbitrary.js";
2
+ import { DeclarativeChoiceAction } from "../daml/daml-choice-action-arbitrary.js";
3
+ import { CantonTestRuntime } from "./canton-test-runtime.js";
4
+ import { CampaignMetricOutcome } from "../campaign/campaign-metrics.js";
5
+ /**
6
+ * Converts a generated declarative action into SDK command types and submits
7
+ * it over the actor's configured Canton route. Choice actions deliberately
8
+ * require an explicit contract resolver: the testing SDK never guesses an
9
+ * active contract ID from stale local state.
10
+ */
11
+ export declare function executeDeclarativeActionAsync(init: {
12
+ readonly action: DeclarativeAction;
13
+ readonly applicationId: string;
14
+ readonly resolveContractIdAsync?: (action: DeclarativeChoiceAction) => Promise<string>;
15
+ readonly runtime: CantonTestRuntime;
16
+ }): Promise<CampaignMetricOutcome>;
@@ -0,0 +1,41 @@
1
+ import { CreateCommand } from "../../core/types/commands/create-command.js";
2
+ import { ExerciseCommand } from "../../core/types/commands/exercise-command.js";
3
+ import { SubmitCommandRequest } from "../../core/types/requests/submit-command-request.js";
4
+ import { TestingConfigurationError } from "../errors/testing-configuration-error.js";
5
+ import { toCampaignMetricOutcome, } from "./canton-test-runtime.js";
6
+ /**
7
+ * Converts a generated declarative action into SDK command types and submits
8
+ * it over the actor's configured Canton route. Choice actions deliberately
9
+ * require an explicit contract resolver: the testing SDK never guesses an
10
+ * active contract ID from stale local state.
11
+ */
12
+ export async function executeDeclarativeActionAsync(init) {
13
+ const route = init.runtime.resolveRoute(init.action.actor);
14
+ const command = "choice" in init.action
15
+ ? await createExerciseCommandAsync(init.action, init.resolveContractIdAsync)
16
+ : new CreateCommand({
17
+ templateId: init.action.templateId,
18
+ payload: { ...init.action.payload },
19
+ });
20
+ return toCampaignMetricOutcome(await init.runtime.submitAndWaitAsync(init.action.actor, new SubmitCommandRequest({
21
+ applicationId: init.applicationId,
22
+ actAs: route.actAs,
23
+ readAs: route.readAs,
24
+ command,
25
+ })));
26
+ }
27
+ async function createExerciseCommandAsync(action, resolveContractIdAsync) {
28
+ if (resolveContractIdAsync === undefined) {
29
+ throw new TestingConfigurationError(`Declarative choice target '${action.targetKey}' requires resolveContractIdAsync.`);
30
+ }
31
+ const contractId = await resolveContractIdAsync(action);
32
+ if (contractId.length === 0) {
33
+ throw new TestingConfigurationError(`Declarative choice target '${action.targetKey}' resolved an empty contract ID.`);
34
+ }
35
+ return new ExerciseCommand({
36
+ templateId: action.templateId,
37
+ contractId,
38
+ choice: action.choice,
39
+ argument: action.argument,
40
+ });
41
+ }
@@ -0,0 +1,49 @@
1
+ import { DamlTestingCatalog } from "../daml/daml-testing-catalog.js";
2
+ export interface TemplateTarget {
3
+ readonly allChoices?: true;
4
+ readonly actors: readonly string[];
5
+ readonly choices: readonly string[];
6
+ readonly kind: "template";
7
+ readonly templateId: string;
8
+ }
9
+ export interface TemplateCreateTarget {
10
+ readonly actors: readonly string[];
11
+ readonly kind: "template-create";
12
+ readonly templateId: string;
13
+ }
14
+ export interface ExcludedChoiceTarget {
15
+ readonly choice: string;
16
+ readonly kind: "exclude-choice";
17
+ readonly templateId: string;
18
+ }
19
+ export interface ExcludedTemplateTarget {
20
+ readonly kind: "exclude-template";
21
+ readonly templateId: string;
22
+ }
23
+ export interface TemplateTargetBuilder {
24
+ allChoices(): TemplateTarget;
25
+ actors(actors: readonly string[]): TemplateTargetBuilder;
26
+ choice(choice: string): TemplateTarget;
27
+ create(): TemplateCreateTarget;
28
+ }
29
+ export interface ResolvedDeclarativeChoiceTarget {
30
+ readonly actors: readonly string[];
31
+ readonly choice: string;
32
+ readonly key: string;
33
+ readonly templateId: string;
34
+ }
35
+ export interface ResolvedDeclarativeCreateTarget {
36
+ readonly actors: readonly string[];
37
+ readonly key: string;
38
+ readonly kind: "create";
39
+ readonly templateId: string;
40
+ }
41
+ export type ResolvedDeclarativeTarget = ResolvedDeclarativeChoiceTarget | ResolvedDeclarativeCreateTarget;
42
+ export declare function targetTemplate(templateId: string): TemplateTargetBuilder;
43
+ /** Builds one immutable declarative template-choice target without a builder chain. */
44
+ export declare function targetChoice(templateId: string, choice: string, actors: readonly string[]): TemplateTarget;
45
+ /** Builds one immutable declarative contract-create target without a builder chain. */
46
+ export declare function targetCreate(templateId: string, actors: readonly string[]): TemplateCreateTarget;
47
+ export declare function excludeChoice(templateId: string, choice: string): ExcludedChoiceTarget;
48
+ export declare function excludeTemplate(templateId: string): ExcludedTemplateTarget;
49
+ export declare function resolveDeclarativeTargets(catalog: DamlTestingCatalog, descriptors: readonly (TemplateTarget | TemplateCreateTarget | ExcludedChoiceTarget | ExcludedTemplateTarget)[]): readonly ResolvedDeclarativeTarget[];
@@ -0,0 +1,121 @@
1
+ import { TestingConfigurationError } from "../errors/testing-configuration-error.js";
2
+ export function targetTemplate(templateId) {
3
+ let actors = [];
4
+ return Object.freeze({
5
+ allChoices() {
6
+ return Object.freeze({
7
+ kind: "template",
8
+ templateId,
9
+ actors,
10
+ choices: Object.freeze([]),
11
+ allChoices: true,
12
+ });
13
+ },
14
+ actors(value) {
15
+ actors = Object.freeze([...value]);
16
+ return this;
17
+ },
18
+ choice(choice) {
19
+ return Object.freeze({
20
+ kind: "template",
21
+ templateId,
22
+ actors,
23
+ choices: Object.freeze([choice]),
24
+ });
25
+ },
26
+ create() {
27
+ return Object.freeze({
28
+ kind: "template-create",
29
+ templateId,
30
+ actors,
31
+ });
32
+ },
33
+ });
34
+ }
35
+ /** Builds one immutable declarative template-choice target without a builder chain. */
36
+ export function targetChoice(templateId, choice, actors) {
37
+ return Object.freeze({
38
+ kind: "template",
39
+ templateId,
40
+ actors: Object.freeze([...actors]),
41
+ choices: Object.freeze([choice]),
42
+ });
43
+ }
44
+ /** Builds one immutable declarative contract-create target without a builder chain. */
45
+ export function targetCreate(templateId, actors) {
46
+ return Object.freeze({
47
+ kind: "template-create",
48
+ templateId,
49
+ actors: Object.freeze([...actors]),
50
+ });
51
+ }
52
+ export function excludeChoice(templateId, choice) {
53
+ return Object.freeze({
54
+ kind: "exclude-choice",
55
+ templateId,
56
+ choice,
57
+ });
58
+ }
59
+ export function excludeTemplate(templateId) {
60
+ return Object.freeze({
61
+ kind: "exclude-template",
62
+ templateId,
63
+ });
64
+ }
65
+ export function resolveDeclarativeTargets(catalog, descriptors) {
66
+ for (const descriptor of descriptors) {
67
+ if (descriptor.kind === "template") {
68
+ continue;
69
+ }
70
+ const template = catalog.getTemplate(descriptor.templateId);
71
+ if (template === undefined) {
72
+ throw new TestingConfigurationError(`Declarative target '${descriptor.templateId}' is absent from the DAML catalog.`);
73
+ }
74
+ else if (descriptor.kind === "exclude-choice"
75
+ && !template.choices.includes(descriptor.choice)) {
76
+ throw new TestingConfigurationError(`Declarative target '${descriptor.templateId}:${descriptor.choice}' is absent from the DAML catalog.`);
77
+ }
78
+ }
79
+ const excludedTemplates = new Set(descriptors
80
+ .filter((descriptor) => descriptor.kind === "exclude-template")
81
+ .map((descriptor) => descriptor.templateId));
82
+ const excluded = new Set(descriptors
83
+ .filter((descriptor) => descriptor.kind === "exclude-choice")
84
+ .map((descriptor) => `${descriptor.templateId}:${descriptor.choice}`));
85
+ return descriptors
86
+ .filter((descriptor) => descriptor.kind === "template" || descriptor.kind === "template-create")
87
+ .flatMap((descriptor) => {
88
+ const template = catalog.getTemplate(descriptor.templateId);
89
+ if (template === undefined) {
90
+ throw new TestingConfigurationError(`Declarative target '${descriptor.templateId}' is absent from the DAML catalog.`);
91
+ }
92
+ else if (descriptor.kind === "template-create") {
93
+ return [Object.freeze({
94
+ key: `${descriptor.templateId}:create`,
95
+ templateId: descriptor.templateId,
96
+ actors: descriptor.actors,
97
+ kind: "create",
98
+ })];
99
+ }
100
+ else {
101
+ if (descriptor.allChoices === true && excludedTemplates.has(descriptor.templateId)) {
102
+ return [];
103
+ }
104
+ const choices = (descriptor.allChoices === true
105
+ ? template.choices.filter((choice) => !excluded.has(`${descriptor.templateId}:${choice}`))
106
+ : descriptor.choices);
107
+ const missingChoice = choices.find((choice) => !template.choices.includes(choice));
108
+ if (missingChoice !== undefined) {
109
+ throw new TestingConfigurationError(`Declarative target '${descriptor.templateId}:${missingChoice}' is absent from the DAML catalog.`);
110
+ }
111
+ return choices
112
+ .map((choice) => Object.freeze({
113
+ key: `${descriptor.templateId}:${choice}`,
114
+ templateId: descriptor.templateId,
115
+ choice,
116
+ actors: descriptor.actors,
117
+ }));
118
+ }
119
+ })
120
+ .sort((left, right) => left.key.localeCompare(right.key));
121
+ }
@@ -1,4 +1,5 @@
1
1
  import { GrpcTransport as ProtobufGrpcTransport } from "@protobuf-ts/grpc-transport";
2
+ import { GrpcTransportError } from "../../core/errors/grpc-transport-error.js";
2
3
  import { PackageServiceClient as ParticipantPackageServiceClient, } from "./generated/canton/com/digitalasset/canton/admin/participant/v30/package_service.client.js";
3
4
  import { PartyManagementServiceClient as ParticipantPartyManagementServiceClient, } from "./generated/canton/com/digitalasset/canton/admin/participant/v30/party_management_service.client.js";
4
5
  import { ParticipantInspectionServiceClient, } from "./generated/canton/com/digitalasset/canton/admin/participant/v30/participant_inspection_service.client.js";
@@ -90,7 +91,7 @@ export function createGrpcOperations(options, endpoint, grpcChannelSecurity, dep
90
91
  ?? new InteractiveSubmissionServiceClient(rpcTransport);
91
92
  const commandServiceClient = dependencies.commandServiceClient
92
93
  ?? new CommandServiceClient(rpcTransport);
93
- return {
94
+ const operations = {
94
95
  async disposeAsync() {
95
96
  rpcTransport.close();
96
97
  },
@@ -471,6 +472,7 @@ export function createGrpcOperations(options, endpoint, grpcChannelSecurity, dep
471
472
  return await unwrapUnaryResponse(interactiveSubmissionServiceClient.executeSubmissionAndWait(request, callOptions));
472
473
  },
473
474
  };
475
+ return wrapGrpcOperations(operations, options.onGrpcError);
474
476
  }
475
477
  async function buildCallOptionsForLedgerSurfaceAsync(options, requestOptions) {
476
478
  return buildGrpcCallOptionsAsync(options.ledgerAuthProvider, options.defaultRequestTimeoutMs, requestOptions);
@@ -487,6 +489,34 @@ function normalizeGrpcHost(endpoint) {
487
489
  }
488
490
  return endpoint;
489
491
  }
492
+ function wrapGrpcOperations(operations, onGrpcError) {
493
+ return new Proxy(operations, {
494
+ get(target, property, receiver) {
495
+ const operation = Reflect.get(target, property, receiver);
496
+ if (typeof operation !== "function") {
497
+ return operation;
498
+ }
499
+ return async (...args) => {
500
+ try {
501
+ return await operation.apply(target, args);
502
+ }
503
+ catch (error) {
504
+ const parsedError = GrpcTransportError.fromUnknown(error);
505
+ if (parsedError === undefined) {
506
+ throw error;
507
+ }
508
+ try {
509
+ onGrpcError?.(parsedError);
510
+ }
511
+ catch {
512
+ // Error observers must not replace the RPC failure.
513
+ }
514
+ throw parsedError;
515
+ }
516
+ };
517
+ },
518
+ });
519
+ }
490
520
  async function unwrapUnaryResponse(call) {
491
521
  return await call.response;
492
522
  }
@@ -84,7 +84,7 @@ import { TopologyListPartiesRequest } from "../../core/types/requests/topology-l
84
84
  import { TopologyListVettedPackagesRequest } from "../../core/types/requests/topology-list-vetted-packages-request.js";
85
85
  import { TrafficControlStateRequest } from "../../core/types/requests/traffic-control-state-request.js";
86
86
  import { UploadDarFileRequest } from "../../core/types/requests/upload-dar-file-request.js";
87
- import { ICommandSigner } from "../../core/signing/command-signer.interface.js";
87
+ import { CommandSigners, ICommandSigner } from "../../core/signing/command-signer.interface.js";
88
88
  import { AllocatePartyResponse as SdkAllocatePartyResponse } from "../../core/types/responses/allocate-party-response.js";
89
89
  import { AllocateExternalPartyResponse } from "../../core/types/responses/allocate-external-party-response.js";
90
90
  import { AddPartyAsyncResponse } from "../../core/types/responses/add-party-async-response.js";
@@ -275,7 +275,7 @@ export declare class GrpcTransport implements ITransport {
275
275
  getUpdateByHashAsync(request: GetUpdateByHashRequest, options?: RequestOptions): Promise<GetUpdateByHashResponse>;
276
276
  getUpdatesPageAsync(request: GetUpdatesPageRequest, options?: RequestOptions): Promise<GetUpdatesPageResponse>;
277
277
  getCompletionsAsync(request: GetCompletionsRequest, observer: CompletionObserver, options?: RequestOptions): Promise<void>;
278
- submitCommandAsync(request: SubmitCommandRequest, signer?: ICommandSigner, options?: RequestOptions): Promise<SubmitCommandResponse>;
278
+ submitCommandAsync(request: SubmitCommandRequest, signer?: ICommandSigner | CommandSigners, options?: RequestOptions): Promise<SubmitCommandResponse>;
279
279
  private throwIfDisposed;
280
280
  private throwPartyTopologyReadCompatibilityError;
281
281
  private isProtobufDeserializationFailure;
@@ -500,6 +500,8 @@ export class GrpcTransport {
500
500
  this.throwIfDisposed();
501
501
  const payload = await this.operations.queryContractsAsync(mapGrpcQueryContractsRequest({
502
502
  party: request.party,
503
+ parties: request.parties,
504
+ allParties: request.allParties,
503
505
  templateId: request.templateId,
504
506
  interfaceId: request.interfaceId,
505
507
  includeInterfaceView: request.includeInterfaceView,
@@ -581,13 +583,13 @@ export class GrpcTransport {
581
583
  const payload = await this.operations.submitCommandAsync(mapGrpcSubmitCommandRequest(request), options);
582
584
  return mapGrpcSubmitCommand(payload);
583
585
  }
584
- if (request.actAs.length !== 1) {
586
+ else if (request.actAs.length !== 1 && !("signAsync" in signer)) {
585
587
  throw new ValidationError("interactive gRPC command signing currently requires exactly one actAs party");
586
588
  }
587
- if (!this.operations.prepareSubmissionAsync) {
589
+ else if (!this.operations.prepareSubmissionAsync) {
588
590
  throw new NotSupportedError("interactive gRPC command signing is not available on this transport");
589
591
  }
590
- if (!this.operations.executeSubmissionAndWaitAsync) {
592
+ else if (!this.operations.executeSubmissionAndWaitAsync) {
591
593
  throw new NotSupportedError("interactive gRPC command signing is not available on this transport");
592
594
  }
593
595
  const commandId = randomUUID();
@@ -599,17 +601,18 @@ export class GrpcTransport {
599
601
  else if (prepared.preparedTransactionHash.length === 0) {
600
602
  throw new ValidationError("interactive prepare submission did not return a preparedTransactionHash");
601
603
  }
602
- const signerResult = await signer.signAsync(new SignCommandRequest({
603
- payload: prepared.preparedTransactionHash,
604
- party: request.actAs[0],
605
- algorithmHint: "ed25519",
604
+ const signerResults = await Promise.all(request.actAs.map(async (party) => {
605
+ const partySigner = "signAsync" in signer ? signer : signer[party];
606
+ if (partySigner === undefined)
607
+ throw new ValidationError(`interactive command signing requires a signer for ${party}`);
608
+ return { party, result: await partySigner.signAsync(new SignCommandRequest({ payload: prepared.preparedTransactionHash, party, algorithmHint: "ed25519" })) };
606
609
  }));
607
610
  const executed = await this.operations.executeSubmissionAndWaitAsync(mapGrpcExecuteSubmissionAndWaitRequest({
608
611
  request,
609
612
  preparedTransaction: prepared.preparedTransaction,
610
613
  hashingSchemeVersion: prepared.hashingSchemeVersion,
611
614
  submissionId,
612
- signerResult,
615
+ signerResults,
613
616
  }), options);
614
617
  return mapGrpcInteractiveSubmitCommand(executed);
615
618
  }
@@ -2,6 +2,8 @@ import { randomUUID } from "node:crypto";
2
2
  import { ValidationError } from "../../../core/errors/validation-error.js";
3
3
  import { CreateAndExerciseCommand } from "../../../core/types/commands/create-and-exercise-command.js";
4
4
  import { CreateCommand } from "../../../core/types/commands/create-command.js";
5
+ import { DamlNumeric } from "../../../core/types/daml-numeric.js";
6
+ import { DamlParty } from "../../../core/types/daml-party.js";
5
7
  import { ExerciseByKeyCommand } from "../../../core/types/commands/exercise-by-key-command.js";
6
8
  import { ExerciseCommand } from "../../../core/types/commands/exercise-command.js";
7
9
  import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
@@ -18,13 +20,16 @@ export function mapGrpcSubmitCommandRequest(request) {
18
20
  actAs: [...request.actAs],
19
21
  readAs: [...request.readAs],
20
22
  submissionId: "",
21
- disclosedContracts: [],
22
- synchronizerId: "",
23
+ disclosedContracts: request.disclosedContracts.map(mapGrpcDisclosedContract),
24
+ synchronizerId: request.synchronizerId ?? "",
23
25
  packageIdSelectionPreference: [],
24
26
  prefetchContractKeys: [],
25
27
  },
26
28
  };
27
29
  }
30
+ function mapGrpcDisclosedContract(value) {
31
+ return { createdEventBlob: value.createdEventBlob, contractId: value.contractId ?? "", synchronizerId: value.synchronizerId ?? "", templateId: value.templateId === undefined ? undefined : { packageId: value.templateId.packageId, moduleName: value.templateId.moduleName, entityName: value.templateId.entityName } };
32
+ }
28
33
  export function mapGrpcSubmitCommand(payload) {
29
34
  return new SubmitCommandResponse({
30
35
  commandId: "commandId" in payload ? payload.commandId : undefined,
@@ -106,6 +111,22 @@ export function mapValue(value) {
106
111
  },
107
112
  };
108
113
  }
114
+ else if (value instanceof DamlParty) {
115
+ return {
116
+ sum: {
117
+ oneofKind: "party",
118
+ party: value.value,
119
+ },
120
+ };
121
+ }
122
+ else if (value instanceof DamlNumeric) {
123
+ return {
124
+ sum: {
125
+ oneofKind: "numeric",
126
+ numeric: value.value,
127
+ },
128
+ };
129
+ }
109
130
  else if (typeof value === "string") {
110
131
  return {
111
132
  sum: {
@@ -5,7 +5,9 @@ import { GetContractRequest as GrpcGetContractRequest } from "../generated/canto
5
5
  import { GetContractResponse as GrpcGetContractResponse } from "../generated/canton/com/daml/ledger/api/v2/contract_service.js";
6
6
  import { GetActiveContractsPageRequest } from "../generated/canton/com/daml/ledger/api/v2/state_service.js";
7
7
  export declare function mapGrpcQueryContractsRequest(request: {
8
- party: string;
8
+ party?: string;
9
+ parties?: readonly string[];
10
+ allParties?: boolean;
9
11
  templateId?: string;
10
12
  interfaceId?: string;
11
13
  includeInterfaceView?: boolean;
@@ -30,10 +30,23 @@ export function mapGrpcGetContract(payload) {
30
30
  });
31
31
  }
32
32
  function createEventFormat(request) {
33
+ const filters = createFilters(request);
34
+ const parties = request.parties ?? (request.party === undefined ? [] : [request.party]);
35
+ if (request.allParties === true) {
36
+ if (parties.length > 0) {
37
+ throw new ValidationError("allParties cannot be combined with party filters");
38
+ }
39
+ return {
40
+ filtersByParty: {},
41
+ filtersForAnyParty: filters,
42
+ verbose: true,
43
+ };
44
+ }
45
+ else if (parties.length === 0) {
46
+ throw new ValidationError("A party filter or allParties is required");
47
+ }
33
48
  return {
34
- filtersByParty: {
35
- [request.party]: createFilters(request),
36
- },
49
+ filtersByParty: Object.fromEntries(parties.map((party) => [party, filters])),
37
50
  verbose: true,
38
51
  };
39
52
  }
@@ -9,7 +9,10 @@ export declare function mapGrpcExecuteSubmissionAndWaitRequest(init: {
9
9
  preparedTransaction: PreparedTransaction;
10
10
  hashingSchemeVersion: HashingSchemeVersion;
11
11
  submissionId: string;
12
- signerResult: SignCommandResult;
12
+ signerResults: readonly {
13
+ readonly party: string;
14
+ readonly result: SignCommandResult;
15
+ }[];
13
16
  }): ExecuteSubmissionAndWaitRequest;
14
17
  export declare function mapGrpcInteractiveSubmitCommand(payload: ExecuteSubmissionAndWaitResponse): SubmitCommandResponse;
15
18
  export declare function mapGrpcSignature(result: SignCommandResult): Signature;
@@ -9,8 +9,8 @@ export function mapGrpcPrepareSubmissionRequest(request, commandId) {
9
9
  commands: [mapGrpcLedgerCommand(request.command)],
10
10
  actAs: [...request.actAs],
11
11
  readAs: [...request.readAs],
12
- disclosedContracts: [],
13
- synchronizerId: "",
12
+ disclosedContracts: request.disclosedContracts.map(value => ({ createdEventBlob: value.createdEventBlob, contractId: value.contractId ?? "", synchronizerId: value.synchronizerId ?? "", templateId: value.templateId === undefined ? undefined : { packageId: value.templateId.packageId, moduleName: value.templateId.moduleName, entityName: value.templateId.entityName } })),
13
+ synchronizerId: request.synchronizerId ?? "",
14
14
  packageIdSelectionPreference: [],
15
15
  prefetchContractKeys: [],
16
16
  verboseHashing: false,
@@ -20,12 +20,7 @@ export function mapGrpcExecuteSubmissionAndWaitRequest(init) {
20
20
  return {
21
21
  preparedTransaction: init.preparedTransaction,
22
22
  partySignatures: {
23
- signatures: [
24
- {
25
- party: init.request.actAs[0] ?? "",
26
- signatures: [mapGrpcSignature(init.signerResult)],
27
- },
28
- ],
23
+ signatures: init.signerResults.map(({ party, result }) => ({ party, signatures: [mapGrpcSignature(result)] })),
29
24
  },
30
25
  deduplicationPeriod: {
31
26
  oneofKind: undefined,