@distrohelena/canton-typescript-sdk 0.1.4 → 0.1.6

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 (254) 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 +4 -3
  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/sign-command-request.d.ts +4 -0
  8. package/dist/core/signing/sign-command-request.js +4 -0
  9. package/dist/core/signing/sign-command-result.d.ts +2 -0
  10. package/dist/core/signing/sign-command-result.js +9 -0
  11. package/dist/core/transports/transport.interface.d.ts +2 -2
  12. package/dist/core/types/canton-hash-purpose.d.ts +2 -1
  13. package/dist/core/types/canton-hash-purpose.js +1 -0
  14. package/dist/core/types/commands/create-and-exercise-command.js +1 -1
  15. package/dist/core/types/commands/exercise-by-key-command.js +2 -2
  16. package/dist/core/types/commands/exercise-command.js +2 -2
  17. package/dist/core/types/daml-numeric.d.ts +6 -0
  18. package/dist/core/types/daml-numeric.js +14 -0
  19. package/dist/core/types/daml-party.d.ts +6 -0
  20. package/dist/core/types/daml-party.js +14 -0
  21. package/dist/core/types/requests/create-decentralized-party-request.d.ts +41 -0
  22. package/dist/core/types/requests/create-decentralized-party-request.js +82 -0
  23. package/dist/core/types/requests/create-external-party-request.d.ts +42 -0
  24. package/dist/core/types/requests/create-external-party-request.js +47 -0
  25. package/dist/core/types/requests/finalize-decentralized-party-request.d.ts +39 -0
  26. package/dist/core/types/requests/finalize-decentralized-party-request.js +42 -0
  27. package/dist/core/types/requests/get-active-contracts-page-request.d.ts +15 -2
  28. package/dist/core/types/requests/get-active-contracts-page-request.js +4 -0
  29. package/dist/core/types/requests/submit-command-request.d.ts +2 -0
  30. package/dist/core/types/requests/submit-command-request.js +2 -0
  31. package/dist/core/types/topology/topology-signature-format.d.ts +2 -1
  32. package/dist/core/types/topology/topology-signature-format.js +1 -0
  33. package/dist/daml-lf/container/dar-archive-entry.d.ts +8 -0
  34. package/dist/daml-lf/container/dar-archive-entry.js +8 -0
  35. package/dist/daml-lf/container/dar-archive-loader.js +14 -0
  36. package/dist/daml-lf/container/dar-archive.d.ts +6 -0
  37. package/dist/daml-lf/container/dar-archive.js +4 -0
  38. package/dist/daml-lf/container/dar-source-bundle-loader.d.ts +5 -0
  39. package/dist/daml-lf/container/dar-source-bundle-loader.js +33 -0
  40. package/dist/daml-lf/container/dar-source-bundle.d.ts +45 -0
  41. package/dist/daml-lf/container/dar-source-bundle.js +11 -0
  42. package/dist/daml-lf/container/dar-source-file-entry.d.ts +8 -0
  43. package/dist/daml-lf/container/dar-source-file-entry.js +8 -0
  44. package/dist/daml-lf/daml-lf-compilation.d.ts +12 -0
  45. package/dist/daml-lf/daml-lf-compilation.js +35 -0
  46. package/dist/daml-lf/index.d.ts +11 -0
  47. package/dist/daml-lf/index.js +10 -0
  48. package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.d.ts +43 -0
  49. package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.js +933 -0
  50. package/dist/daml-lf/interpreter/daml-lf-evaluator.d.ts +95 -0
  51. package/dist/daml-lf/interpreter/daml-lf-evaluator.js +1131 -0
  52. package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.d.ts +3 -0
  53. package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.js +6 -1
  54. package/dist/daml-lf/interpreter/daml-lf-lexical-scope.d.ts +13 -0
  55. package/dist/daml-lf/interpreter/daml-lf-lexical-scope.js +46 -0
  56. package/dist/daml-lf/interpreter/daml-lf-runtime-frame.d.ts +16 -0
  57. package/dist/daml-lf/interpreter/daml-lf-runtime-frame.js +15 -0
  58. package/dist/daml-lf/interpreter/daml-lf-runtime-value.d.ts +21 -0
  59. package/dist/daml-lf/interpreter/daml-lf-runtime-value.js +4 -1
  60. package/dist/daml-lf/interpreter/daml-lf-step-kind.d.ts +7 -0
  61. package/dist/daml-lf/interpreter/daml-lf-step-kind.js +8 -0
  62. package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.d.ts +30 -0
  63. package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.js +1 -0
  64. package/dist/daml-lf/model/daml-lf-builtin-type.d.ts +3 -0
  65. package/dist/daml-lf/model/daml-lf-builtin-type.js +3 -0
  66. package/dist/daml-lf/model/daml-lf-choice.d.ts +5 -0
  67. package/dist/daml-lf/model/daml-lf-choice.js +4 -0
  68. package/dist/daml-lf/model/daml-lf-expression-path.d.ts +2 -0
  69. package/dist/daml-lf/model/daml-lf-expression-path.js +81 -0
  70. package/dist/daml-lf/model/daml-lf-expression.d.ts +146 -0
  71. package/dist/daml-lf/model/daml-lf-expression.js +71 -0
  72. package/dist/daml-lf/model/daml-lf-template.d.ts +2 -0
  73. package/dist/daml-lf/model/daml-lf-template.js +2 -0
  74. package/dist/daml-lf/model/daml-lf-type.d.ts +2 -0
  75. package/dist/daml-lf/model/daml-lf-type.js +4 -0
  76. package/dist/daml-lf/model/lf-2-model-mapper.d.ts +5 -0
  77. package/dist/daml-lf/model/lf-2-model-mapper.js +445 -12
  78. package/dist/debugger/errors/replay-determinism.exception.d.ts +3 -0
  79. package/dist/debugger/errors/replay-determinism.exception.js +3 -0
  80. package/dist/debugger/errors/replay-missing-package.exception.d.ts +3 -0
  81. package/dist/debugger/errors/replay-missing-package.exception.js +3 -0
  82. package/dist/debugger/errors/replay-missing-source.exception.d.ts +3 -0
  83. package/dist/debugger/errors/replay-missing-source.exception.js +3 -0
  84. package/dist/debugger/errors/replay-source-map.exception.d.ts +3 -0
  85. package/dist/debugger/errors/replay-source-map.exception.js +3 -0
  86. package/dist/debugger/errors/replay-state-hydration.exception.d.ts +3 -0
  87. package/dist/debugger/errors/replay-state-hydration.exception.js +3 -0
  88. package/dist/debugger/errors/replay-unsupported-lf-construct.exception.d.ts +3 -0
  89. package/dist/debugger/errors/replay-unsupported-lf-construct.exception.js +3 -0
  90. package/dist/debugger/errors/replay-unsupported-update.exception.d.ts +3 -0
  91. package/dist/debugger/errors/replay-unsupported-update.exception.js +3 -0
  92. package/dist/debugger/index.d.ts +31 -0
  93. package/dist/debugger/index.js +31 -0
  94. package/dist/debugger/ledger-replay-debugger-client.d.ts +31 -0
  95. package/dist/debugger/ledger-replay-debugger-client.js +53 -0
  96. package/dist/debugger/replay/ledger-replay-environment-builder.d.ts +95 -0
  97. package/dist/debugger/replay/ledger-replay-environment-builder.js +249 -0
  98. package/dist/debugger/replay/ledger-replay-session-loader.d.ts +78 -0
  99. package/dist/debugger/replay/ledger-replay-session-loader.js +565 -0
  100. package/dist/debugger/replay/replay-artifact-resolver.d.ts +30 -0
  101. package/dist/debugger/replay/replay-artifact-resolver.js +210 -0
  102. package/dist/debugger/replay/replay-determinism-validator.d.ts +12 -0
  103. package/dist/debugger/replay/replay-determinism-validator.js +161 -0
  104. package/dist/debugger/replay/replay-entrypoint-definition-resolver.d.ts +40 -0
  105. package/dist/debugger/replay/replay-entrypoint-definition-resolver.js +337 -0
  106. package/dist/debugger/replay/replay-entrypoint.d.ts +22 -0
  107. package/dist/debugger/replay/replay-entrypoint.js +14 -0
  108. package/dist/debugger/replay/replay-ledger-value-normalizer.d.ts +7 -0
  109. package/dist/debugger/replay/replay-ledger-value-normalizer.js +194 -0
  110. package/dist/debugger/replay/replay-update-loader.d.ts +24 -0
  111. package/dist/debugger/replay/replay-update-loader.js +94 -0
  112. package/dist/debugger/replay/replay-update-visibility-validator.d.ts +19 -0
  113. package/dist/debugger/replay/replay-update-visibility-validator.js +19 -0
  114. package/dist/debugger/session/in-memory-replay-session-store.d.ts +27 -0
  115. package/dist/debugger/session/in-memory-replay-session-store.js +109 -0
  116. package/dist/debugger/session/replay-phase.d.ts +7 -0
  117. package/dist/debugger/session/replay-phase.js +8 -0
  118. package/dist/debugger/session/replay-scope.d.ts +10 -0
  119. package/dist/debugger/session/replay-scope.js +10 -0
  120. package/dist/debugger/session/replay-session-metadata.d.ts +10 -0
  121. package/dist/debugger/session/replay-session-metadata.js +10 -0
  122. package/dist/debugger/session/replay-session-request.d.ts +6 -0
  123. package/dist/debugger/session/replay-session-request.js +10 -0
  124. package/dist/debugger/session/replay-session.d.ts +12 -0
  125. package/dist/debugger/session/replay-session.js +10 -0
  126. package/dist/debugger/session/replay-source-location.d.ts +17 -0
  127. package/dist/debugger/session/replay-source-location.js +16 -0
  128. package/dist/debugger/session/replay-stack-frame.d.ts +8 -0
  129. package/dist/debugger/session/replay-stack-frame.js +8 -0
  130. package/dist/debugger/session/replay-state-delta.d.ts +29 -0
  131. package/dist/debugger/session/replay-state-delta.js +24 -0
  132. package/dist/debugger/session/replay-step-advance-result.d.ts +24 -0
  133. package/dist/debugger/session/replay-step-advance-result.js +16 -0
  134. package/dist/debugger/session/replay-step.d.ts +30 -0
  135. package/dist/debugger/session/replay-step.js +24 -0
  136. package/dist/debugger/session/replay-value-preview.d.ts +8 -0
  137. package/dist/debugger/session/replay-value-preview.js +15 -0
  138. package/dist/debugger/source/daml-source-mapper.d.ts +12 -0
  139. package/dist/debugger/source/daml-source-mapper.js +21 -0
  140. package/dist/debugger/source/dar-source-map-metadata.d.ts +26 -0
  141. package/dist/debugger/source/dar-source-map-metadata.js +10 -0
  142. package/dist/debugger/source/source-coverage-validator.d.ts +8 -0
  143. package/dist/debugger/source/source-coverage-validator.js +16 -0
  144. package/dist/debugger/source/source-indexed-compilation.d.ts +45 -0
  145. package/dist/debugger/source/source-indexed-compilation.js +110 -0
  146. package/dist/debugger/source/source-mapping-precision.d.ts +5 -0
  147. package/dist/debugger/source/source-mapping-precision.js +4 -0
  148. package/dist/index.d.ts +20 -0
  149. package/dist/index.js +12 -0
  150. package/dist/query/cache/memory-query-cache.d.ts +9 -0
  151. package/dist/query/cache/memory-query-cache.js +24 -0
  152. package/dist/query/cache/query-cache-store.d.ts +5 -0
  153. package/dist/query/cache/query-cache-store.js +1 -0
  154. package/dist/query/canton-manager-options.d.ts +17 -0
  155. package/dist/query/canton-manager-options.js +1 -0
  156. package/dist/query/canton-manager.d.ts +11 -0
  157. package/dist/query/canton-manager.js +42 -0
  158. package/dist/query/errors/pqs-query-error.d.ts +10 -0
  159. package/dist/query/errors/pqs-query-error.js +11 -0
  160. package/dist/query/errors/pqs-schema-profile-error.d.ts +3 -0
  161. package/dist/query/errors/pqs-schema-profile-error.js +3 -0
  162. package/dist/query/errors/query-capability-error.d.ts +7 -0
  163. package/dist/query/errors/query-capability-error.js +10 -0
  164. package/dist/query/grpc/grpc-contract-query-client.d.ts +32 -0
  165. package/dist/query/grpc/grpc-contract-query-client.js +126 -0
  166. package/dist/query/model-types.d.ts +258 -0
  167. package/dist/query/model-types.js +14 -0
  168. package/dist/query/pqs/pqs-pool.d.ts +13 -0
  169. package/dist/query/pqs/pqs-pool.js +18 -0
  170. package/dist/query/pqs/pqs-query-client.d.ts +49 -0
  171. package/dist/query/pqs/pqs-query-client.js +324 -0
  172. package/dist/query/pqs/pqs-schema-profile.d.ts +25 -0
  173. package/dist/query/pqs/pqs-schema-profile.js +120 -0
  174. package/dist/query/pqs/pqs-sql-compiler.d.ts +7 -0
  175. package/dist/query/pqs/pqs-sql-compiler.js +132 -0
  176. package/dist/query/pqs/read-only-sql.d.ts +1 -0
  177. package/dist/query/pqs/read-only-sql.js +35 -0
  178. package/dist/query/query-client.d.ts +61 -0
  179. package/dist/query/query-client.js +1 -0
  180. package/dist/query/query-source.d.ts +4 -0
  181. package/dist/query/query-source.js +5 -0
  182. package/dist/services/commands/command-payload-builder.js +3 -3
  183. package/dist/services/commands/command-submission-pipeline.js +1 -7
  184. package/dist/services/party-management/decentralized-party-lifecycle.d.ts +6 -0
  185. package/dist/services/party-management/decentralized-party-lifecycle.js +82 -0
  186. package/dist/services/party-management/party-management-service-client.d.ts +16 -1
  187. package/dist/services/party-management/party-management-service-client.js +142 -1
  188. package/dist/services/topology-manager-write/topology-signed-transaction-assembler.js +4 -0
  189. package/dist/testing/campaign/campaign-artifact.d.ts +20 -0
  190. package/dist/testing/campaign/campaign-artifact.js +147 -0
  191. package/dist/testing/campaign/campaign-definition.d.ts +9 -0
  192. package/dist/testing/campaign/campaign-definition.js +78 -0
  193. package/dist/testing/campaign/campaign-metrics.d.ts +32 -0
  194. package/dist/testing/campaign/campaign-metrics.js +26 -0
  195. package/dist/testing/campaign/campaign-model.d.ts +11 -0
  196. package/dist/testing/campaign/campaign-model.js +21 -0
  197. package/dist/testing/campaign/campaign-runner.d.ts +99 -0
  198. package/dist/testing/campaign/campaign-runner.js +194 -0
  199. package/dist/testing/campaign/campaign-scheduler.d.ts +40 -0
  200. package/dist/testing/campaign/campaign-scheduler.js +75 -0
  201. package/dist/testing/campaign/campaign-types.d.ts +52 -0
  202. package/dist/testing/campaign/campaign-types.js +11 -0
  203. package/dist/testing/daml/daml-action-arbitrary.d.ts +13 -0
  204. package/dist/testing/daml/daml-action-arbitrary.js +24 -0
  205. package/dist/testing/daml/daml-choice-action-arbitrary.d.ts +18 -0
  206. package/dist/testing/daml/daml-choice-action-arbitrary.js +27 -0
  207. package/dist/testing/daml/daml-create-action-arbitrary.d.ts +19 -0
  208. package/dist/testing/daml/daml-create-action-arbitrary.js +34 -0
  209. package/dist/testing/daml/daml-testing-catalog.d.ts +38 -0
  210. package/dist/testing/daml/daml-testing-catalog.js +40 -0
  211. package/dist/testing/daml/daml-value-arbitrary.d.ts +8 -0
  212. package/dist/testing/daml/daml-value-arbitrary.js +43 -0
  213. package/dist/testing/daml/declarative-campaign-arbitrary.d.ts +15 -0
  214. package/dist/testing/daml/declarative-campaign-arbitrary.js +30 -0
  215. package/dist/testing/errors/invariant-campaign-failure.d.ts +24 -0
  216. package/dist/testing/errors/invariant-campaign-failure.js +37 -0
  217. package/dist/testing/errors/testing-configuration-error.d.ts +3 -0
  218. package/dist/testing/errors/testing-configuration-error.js +6 -0
  219. package/dist/testing/handlers/handler.d.ts +19 -0
  220. package/dist/testing/handlers/handler.js +31 -0
  221. package/dist/testing/index.d.ts +22 -0
  222. package/dist/testing/index.js +22 -0
  223. package/dist/testing/runtime/campaign-isolation.d.ts +14 -0
  224. package/dist/testing/runtime/campaign-isolation.js +23 -0
  225. package/dist/testing/runtime/canton-test-runtime.d.ts +58 -0
  226. package/dist/testing/runtime/canton-test-runtime.js +138 -0
  227. package/dist/testing/runtime/declarative-action-executor.d.ts +16 -0
  228. package/dist/testing/runtime/declarative-action-executor.js +41 -0
  229. package/dist/testing/targets/target.d.ts +49 -0
  230. package/dist/testing/targets/target.js +121 -0
  231. package/dist/transports/grpc/grpc-channel-factory.d.ts +4 -0
  232. package/dist/transports/grpc/grpc-channel-factory.js +42 -1
  233. package/dist/transports/grpc/grpc-transport.d.ts +2 -2
  234. package/dist/transports/grpc/grpc-transport.js +42 -3
  235. package/dist/transports/grpc/mappers/commands-mapper.d.ts +10 -2
  236. package/dist/transports/grpc/mappers/commands-mapper.js +30 -12
  237. package/dist/transports/grpc/mappers/contracts-mapper.d.ts +3 -1
  238. package/dist/transports/grpc/mappers/contracts-mapper.js +16 -3
  239. package/dist/transports/grpc/mappers/interactive-command-mapper.d.ts +15 -0
  240. package/dist/transports/grpc/mappers/interactive-command-mapper.js +54 -0
  241. package/dist/transports/grpc/mappers/topology-manager-write-mapper.js +59 -1
  242. package/dist/transports/json/json-transport.d.ts +2 -2
  243. package/dist/transports/json/json-transport.js +2 -2
  244. package/dist/transports/json/mappers/commands-mapper.js +23 -9
  245. package/node/.generated/start-local/additional-config.extra-participants.conf +37 -0
  246. package/node/.generated/start-local/additional-config.extra-validators.conf +35 -0
  247. package/node/.generated/start-local/compose-extra-participants.yaml +147 -0
  248. package/node/.generated/start-local/extra-participants.env +30 -0
  249. package/node/es256-jwt.mjs +177 -0
  250. package/node/start-local.sh +886 -0
  251. package/node/stop-local.sh +200 -0
  252. package/node/test-start-local.sh +354 -0
  253. package/node/test-stop-local.sh +112 -0
  254. package/package.json +21 -2
@@ -0,0 +1,61 @@
1
+ import { QuerySource } from "./query-source.js";
2
+ import { ContractTypeOrderBy, ContractTypeRow, ContractTypeSelect, ContractTypeUnique, ContractTypeWhere, ContractCountArgs, ContractFindManyArgs, ContractFindUniqueArgs, ContractRow, EventOrderBy, EventRow, EventSelect, EventUnique, EventWhere, ExerciseOrderBy, ExerciseRow, ExerciseSelect, ExerciseTypeOrderBy, ExerciseTypeRow, ExerciseTypeSelect, ExerciseTypeUnique, ExerciseTypeWhere, ExerciseWhere, PackageOrderBy, PackageRow, PackageSelect, PackageUnique, PackageWhere, TransactionOrderBy, TransactionRow, TransactionSelect, TransactionUnique, TransactionWhere, WatermarkOrderBy, WatermarkRow, WatermarkSelect, WatermarkUnique, WatermarkWhere } from "./model-types.js";
3
+ export interface FindManyArgs<TWhere, TSelect, TOrderBy> {
4
+ readonly where?: TWhere;
5
+ readonly select?: TSelect;
6
+ readonly orderBy?: TOrderBy;
7
+ readonly skip?: number;
8
+ readonly take?: number;
9
+ }
10
+ export interface QueryDelegate<TRow, TWhere, TSelect, TOrderBy, TUnique> {
11
+ findMany(args?: FindManyArgs<TWhere, TSelect, TOrderBy>): Promise<readonly TRow[]>;
12
+ findUnique(args: {
13
+ readonly where: TUnique;
14
+ readonly select?: TSelect;
15
+ }): Promise<TRow | undefined>;
16
+ count(args?: {
17
+ readonly where?: TWhere;
18
+ }): Promise<number>;
19
+ aggregate(args: {
20
+ readonly where?: TWhere;
21
+ readonly count?: true;
22
+ readonly min?: readonly (keyof TRow)[];
23
+ readonly max?: readonly (keyof TRow)[];
24
+ readonly sum?: readonly (keyof TRow)[];
25
+ }): Promise<{
26
+ readonly count?: number;
27
+ readonly min?: Readonly<Record<string, string | null>>;
28
+ readonly max?: Readonly<Record<string, string | null>>;
29
+ readonly sum?: Readonly<Record<string, string | null>>;
30
+ }>;
31
+ }
32
+ export type QueryCollectionDelegate<TRow, TWhere, TSelect, TOrderBy> = Omit<QueryDelegate<TRow, TWhere, TSelect, TOrderBy, never>, "findUnique">;
33
+ export interface QueryClient {
34
+ readonly source: QuerySource;
35
+ $queryRaw<TRow>(sql: string, values?: readonly unknown[]): Promise<readonly TRow[]>;
36
+ readonly contracts: {
37
+ findMany(args?: ContractFindManyArgs): Promise<readonly ContractRow[]>;
38
+ findUnique(args: ContractFindUniqueArgs): Promise<ContractRow | undefined>;
39
+ count(args?: ContractCountArgs): Promise<number>;
40
+ aggregate(args: {
41
+ readonly where?: ContractCountArgs["where"];
42
+ readonly count?: true;
43
+ readonly min?: readonly ContractNumericField[];
44
+ readonly max?: readonly ContractNumericField[];
45
+ readonly sum?: readonly ContractNumericField[];
46
+ }): Promise<{
47
+ readonly count?: number;
48
+ readonly min?: Readonly<Partial<Record<ContractNumericField, string | null>>>;
49
+ readonly max?: Readonly<Partial<Record<ContractNumericField, string | null>>>;
50
+ readonly sum?: Readonly<Partial<Record<ContractNumericField, string | null>>>;
51
+ }>;
52
+ };
53
+ readonly contractTypes: QueryDelegate<ContractTypeRow, ContractTypeWhere, ContractTypeSelect, ContractTypeOrderBy, ContractTypeUnique>;
54
+ readonly events: QueryDelegate<EventRow, EventWhere, EventSelect, EventOrderBy, EventUnique>;
55
+ readonly exercises: QueryCollectionDelegate<ExerciseRow, ExerciseWhere, ExerciseSelect, ExerciseOrderBy>;
56
+ readonly exerciseTypes: QueryDelegate<ExerciseTypeRow, ExerciseTypeWhere, ExerciseTypeSelect, ExerciseTypeOrderBy, ExerciseTypeUnique>;
57
+ readonly packages: QueryDelegate<PackageRow, PackageWhere, PackageSelect, PackageOrderBy, PackageUnique>;
58
+ readonly transactions: QueryDelegate<TransactionRow, TransactionWhere, TransactionSelect, TransactionOrderBy, TransactionUnique>;
59
+ readonly watermark: QueryDelegate<WatermarkRow, WatermarkWhere, WatermarkSelect, WatermarkOrderBy, WatermarkUnique>;
60
+ }
61
+ export type ContractNumericField = "createdEventOffset" | "archivedEventOffset";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export declare enum QuerySource {
2
+ grpc = "grpc",
3
+ pqs = "pqs"
4
+ }
@@ -0,0 +1,5 @@
1
+ export var QuerySource;
2
+ (function (QuerySource) {
3
+ QuerySource["grpc"] = "grpc";
4
+ QuerySource["pqs"] = "pqs";
5
+ })(QuerySource || (QuerySource = {}));
@@ -18,7 +18,7 @@ function mapCanonicalCommand(command) {
18
18
  payload: command.payload,
19
19
  };
20
20
  }
21
- if (command instanceof ExerciseCommand) {
21
+ else if (command instanceof ExerciseCommand) {
22
22
  return {
23
23
  kind: "exercise",
24
24
  templateId: command.templateId,
@@ -27,7 +27,7 @@ function mapCanonicalCommand(command) {
27
27
  argument: command.argument,
28
28
  };
29
29
  }
30
- if (command instanceof ExerciseByKeyCommand) {
30
+ else if (command instanceof ExerciseByKeyCommand) {
31
31
  return {
32
32
  kind: "exerciseByKey",
33
33
  templateId: command.templateId,
@@ -36,7 +36,7 @@ function mapCanonicalCommand(command) {
36
36
  argument: command.argument,
37
37
  };
38
38
  }
39
- if (command instanceof CreateAndExerciseCommand) {
39
+ else if (command instanceof CreateAndExerciseCommand) {
40
40
  return {
41
41
  kind: "createAndExercise",
42
42
  templateId: command.templateId,
@@ -1,21 +1,15 @@
1
1
  import { NotSupportedError } from "../../core/errors/not-supported-error.js";
2
- import { SignCommandRequest } from "../../core/signing/sign-command-request.js";
3
- import { buildCanonicalCommandPayload } from "./command-payload-builder.js";
4
2
  export class CommandSubmissionPipeline {
5
3
  dependencies;
6
4
  constructor(dependencies) {
7
5
  this.dependencies = dependencies;
8
6
  }
9
7
  async submitAsync(request, options) {
10
- let signed;
11
8
  if (this.dependencies.signer) {
12
9
  if (!this.dependencies.transport.features.supportsCommandSigning) {
13
10
  throw new NotSupportedError("command signing is not supported by the selected transport");
14
11
  }
15
- signed = await this.dependencies.signer.signAsync(new SignCommandRequest({
16
- payload: buildCanonicalCommandPayload(request),
17
- }));
18
12
  }
19
- return this.dependencies.transport.submitCommandAsync(request, signed, options);
13
+ return this.dependencies.transport.submitCommandAsync(request, this.dependencies.signer, options);
20
14
  }
21
15
  }
@@ -0,0 +1,6 @@
1
+ import { CreateDecentralizedPartyRequest } from "../../core/types/requests/create-decentralized-party-request.js";
2
+ import { PreparedDecentralizedParty } from "../../core/types/requests/finalize-decentralized-party-request.js";
3
+ import { GetParticipantIdResponse } from "../../core/types/responses/get-participant-id-response.js";
4
+ import { RequestOptions } from "../../core/types/request-options.js";
5
+ import { TopologyManagerWriteServiceClient } from "../topology-manager-write/topology-manager-write-service-client.js";
6
+ export declare function prepareDecentralizedPartyAsync(request: CreateDecentralizedPartyRequest, localParticipant: GetParticipantIdResponse, topologyWriter: TopologyManagerWriteServiceClient, options?: RequestOptions): Promise<PreparedDecentralizedParty>;
@@ -0,0 +1,82 @@
1
+ import { computeCantonHashHex, computeCantonPublicKeyFingerprint } from "../../core/hashing/canton-hash.js";
2
+ import { ValidationError } from "../../core/errors/validation-error.js";
3
+ import { CantonHashPurpose } from "../../core/types/canton-hash-purpose.js";
4
+ import { PreparedDecentralizedParty } from "../../core/types/requests/finalize-decentralized-party-request.js";
5
+ import { PreparedTopologyTransaction } from "../../core/types/topology/prepared-topology-transaction.js";
6
+ import { GenerateTopologyTransactionsRequest } from "../../core/types/requests/generate-topology-transactions-request.js";
7
+ import { DecentralizedNamespaceDefinition } from "../../core/types/topology/decentralized-namespace-definition.js";
8
+ import { NamespaceDelegation } from "../../core/types/topology/namespace-delegation.js";
9
+ import { PartyToParticipant, PartyToParticipantParticipant } from "../../core/types/topology/party-to-participant.js";
10
+ import { ParticipantPermission } from "../../core/types/topology/participant-permission.js";
11
+ import { TopologyMappingOperation } from "../../core/types/topology/topology-mapping-operation.js";
12
+ import { TopologySigningKeysWithThreshold, TopologySigningPublicKey } from "../../core/types/topology/topology-public-key.js";
13
+ export async function prepareDecentralizedPartyAsync(request, localParticipant, topologyWriter, options) {
14
+ const ownerFingerprints = request.owners.map(fingerprintFor);
15
+ const decentralizedNamespace = deriveNamespace(ownerFingerprints);
16
+ const partyId = `${request.partyHint}::${decentralizedNamespace}`;
17
+ const owners = request.owners.map(toTopologyKey);
18
+ const partyKeys = request.partySigningKeys.map(toTopologyKey);
19
+ const participants = [
20
+ new PartyToParticipantParticipant({
21
+ participantUid: localParticipant.participantId,
22
+ permission: request.localParticipantObservationOnly
23
+ ? ParticipantPermission.observation
24
+ : ParticipantPermission.confirmation,
25
+ }),
26
+ ...request.otherConfirmingParticipantUids.map((participantUid) => new PartyToParticipantParticipant({ participantUid, permission: ParticipantPermission.confirmation })),
27
+ ...request.observingParticipantUids.map((participantUid) => new PartyToParticipantParticipant({ participantUid, permission: ParticipantPermission.observation })),
28
+ ];
29
+ const generated = await topologyWriter.generateTransactionsAsync(new GenerateTopologyTransactionsRequest({
30
+ proposals: [
31
+ { operation: TopologyMappingOperation.addReplace, serial: 1, mapping: new DecentralizedNamespaceDefinition({ decentralizedNamespace, threshold: request.ownerThreshold, owners: ownerFingerprints }) },
32
+ ...owners.map((targetKey) => ({ operation: TopologyMappingOperation.addReplace, serial: 1, mapping: new NamespaceDelegation({ namespace: decentralizedNamespace, targetKey, isRootDelegation: true }) })),
33
+ { operation: TopologyMappingOperation.addReplace, serial: 1, mapping: new PartyToParticipant({ party: partyId, threshold: request.confirmationThreshold, participants, partySigningKeys: new TopologySigningKeysWithThreshold({ threshold: request.partySigningThreshold, keys: partyKeys }) }) },
34
+ ],
35
+ }), options);
36
+ if (generated.generatedTransactions.length !== owners.length + 2) {
37
+ throw new ValidationError("decentralized party generated transaction count does not match proposals");
38
+ }
39
+ const transactions = generated.generatedTransactions.map((transaction) => new PreparedTopologyTransaction({
40
+ serializedTransaction: transaction.serializedTransaction,
41
+ transactionHash: transaction.transactionHash,
42
+ }));
43
+ const signingRequests = transactions.flatMap((transaction, index) => {
44
+ const ownerRequests = ownerFingerprints.map((publicKeyFingerprint) => ({
45
+ id: `${index}:owner:${publicKeyFingerprint}`,
46
+ transactionHash: transaction.transactionHash,
47
+ payload: transaction.transactionHash,
48
+ publicKeyFingerprint,
49
+ role: "owner",
50
+ }));
51
+ return index === transactions.length - 1
52
+ ? [...ownerRequests, ...request.partySigningKeys.map((key) => ({
53
+ id: `${index}:partySigningKey:${fingerprintFor(key)}`,
54
+ transactionHash: transaction.transactionHash,
55
+ payload: transaction.transactionHash,
56
+ publicKeyFingerprint: fingerprintFor(key),
57
+ role: "partySigningKey",
58
+ }))]
59
+ : ownerRequests;
60
+ });
61
+ return new PreparedDecentralizedParty({ synchronizer: request.synchronizer, partyId, decentralizedNamespace, ownerThreshold: request.ownerThreshold, partySigningThreshold: request.partySigningThreshold, transactions, signingRequests });
62
+ }
63
+ function fingerprintFor(value) {
64
+ const fingerprint = computeCantonPublicKeyFingerprint(value.publicKey.keyData, value.publicKey.format);
65
+ if (fingerprint === undefined) {
66
+ throw new ValidationError("decentralized party key requires public key material");
67
+ }
68
+ return fingerprint;
69
+ }
70
+ function deriveNamespace(ownerFingerprints) {
71
+ const encoder = new TextEncoder();
72
+ const chunks = [...ownerFingerprints].sort().flatMap((fingerprint) => {
73
+ const bytes = encoder.encode(fingerprint);
74
+ const length = new Uint8Array(4);
75
+ new DataView(length.buffer).setUint32(0, bytes.length);
76
+ return [...length, ...bytes];
77
+ });
78
+ return computeCantonHashHex(new Uint8Array(chunks), CantonHashPurpose.decentralizedNamespace);
79
+ }
80
+ function toTopologyKey(value) {
81
+ return new TopologySigningPublicKey({ format: value.publicKey.format, publicKey: value.publicKey.keyData, keySpec: value.publicKey.keySpec, usage: ["namespace", "protocol", "proofOfOwnership"] });
82
+ }
@@ -2,6 +2,8 @@ import { ITransport } from "../../core/transports/transport.interface.js";
2
2
  import { RequestOptions } from "../../core/types/request-options.js";
3
3
  import { AllocateExternalPartyRequest } from "../../core/types/requests/allocate-external-party-request.js";
4
4
  import { AllocatePartyRequest } from "../../core/types/requests/allocate-party-request.js";
5
+ import { CreateExternalPartyRequest } from "../../core/types/requests/create-external-party-request.js";
6
+ import { CreateDecentralizedPartyRequest } from "../../core/types/requests/create-decentralized-party-request.js";
5
7
  import { GenerateExternalPartyTopologyRequest } from "../../core/types/requests/generate-external-party-topology-request.js";
6
8
  import { AllocateExternalPartyResponse } from "../../core/types/responses/allocate-external-party-response.js";
7
9
  import { GetParticipantIdRequest } from "../../core/types/requests/get-participant-id-request.js";
@@ -12,9 +14,19 @@ import { GenerateExternalPartyTopologyResponse } from "../../core/types/response
12
14
  import { GetParticipantIdResponse } from "../../core/types/responses/get-participant-id-response.js";
13
15
  import { GetPartiesResponse } from "../../core/types/responses/get-parties-response.js";
14
16
  import { ListKnownPartiesResponse } from "../../core/types/responses/list-known-parties-response.js";
17
+ import { PreparedDecentralizedParty } from "../../core/types/requests/finalize-decentralized-party-request.js";
18
+ import { DecentralizedPartyDetachedSignature } from "../../core/types/requests/finalize-decentralized-party-request.js";
19
+ import { TopologyManagerWriteServiceClient } from "../topology-manager-write/topology-manager-write-service-client.js";
15
20
  export declare class PartyManagementServiceClient {
16
21
  private readonly transport;
17
- constructor(transport: ITransport);
22
+ private readonly topologyWriter?;
23
+ constructor(transport: ITransport, topologyWriter?: TopologyManagerWriteServiceClient | undefined);
24
+ /** Prepares canonical decentralized-party topology for caller-owned signing. Supported on gRPC with participant-admin configuration. */
25
+ prepareDecentralizedPartyAsync(request: CreateDecentralizedPartyRequest, options?: RequestOptions): Promise<PreparedDecentralizedParty>;
26
+ /** Validates detached decentralized-party signatures before allocation. */
27
+ finalizeDecentralizedPartyAsync(prepared: PreparedDecentralizedParty, signatures: readonly DecentralizedPartyDetachedSignature[], _options?: RequestOptions): Promise<AllocateExternalPartyResponse>;
28
+ /** Creates a decentralized party using the per-key callbacks in the request. */
29
+ createDecentralizedPartyAsync(request: CreateDecentralizedPartyRequest, options?: RequestOptions): Promise<AllocateExternalPartyResponse>;
18
30
  /** Lists known parties. Supported on JSON and gRPC. */
19
31
  listKnownPartiesAsync(request: ListKnownPartiesRequest, options?: RequestOptions): Promise<ListKnownPartiesResponse>;
20
32
  /** Reads the host participant identifier. Supported on gRPC; JSON rejects it. */
@@ -27,4 +39,7 @@ export declare class PartyManagementServiceClient {
27
39
  generateExternalPartyTopologyAsync(request: GenerateExternalPartyTopologyRequest, options?: RequestOptions): Promise<GenerateExternalPartyTopologyResponse>;
28
40
  /** Allocates an external party through the ledger-admin API. Supported on gRPC; JSON rejects it. */
29
41
  allocateExternalPartyAsync(request: AllocateExternalPartyRequest, options?: RequestOptions): Promise<AllocateExternalPartyResponse>;
42
+ /** Creates an externally controlled party using caller-provided signing. Supported on gRPC. */
43
+ createExternalPartyAsync(request: CreateExternalPartyRequest, options?: RequestOptions): Promise<AllocateExternalPartyResponse>;
44
+ private signExternalPartyPayloadAsync;
30
45
  }
@@ -1,9 +1,100 @@
1
+ import { AllocateExternalPartyRequest } from "../../core/types/requests/allocate-external-party-request.js";
2
+ import { GenerateExternalPartyTopologyRequest } from "../../core/types/requests/generate-external-party-topology-request.js";
3
+ import { ExternalPartyOnboardingTransaction } from "../../core/types/external-party/external-party-onboarding-transaction.js";
4
+ import { ExternalPartySignature } from "../../core/types/external-party/external-party-signature.js";
5
+ import { GetParticipantIdRequest } from "../../core/types/requests/get-participant-id-request.js";
6
+ import { ValidationError } from "../../core/errors/validation-error.js";
7
+ import { prepareDecentralizedPartyAsync } from "./decentralized-party-lifecycle.js";
8
+ import { NotSupportedError } from "../../core/errors/not-supported-error.js";
9
+ import { computeCantonPublicKeyFingerprint } from "../../core/hashing/canton-hash.js";
1
10
  export class PartyManagementServiceClient {
2
11
  transport;
3
- constructor(transport) {
12
+ topologyWriter;
13
+ constructor(transport, topologyWriter) {
4
14
  this.transport = transport;
15
+ this.topologyWriter = topologyWriter;
5
16
  void this.transport;
6
17
  }
18
+ /** Prepares canonical decentralized-party topology for caller-owned signing. Supported on gRPC with participant-admin configuration. */
19
+ async prepareDecentralizedPartyAsync(request, options) {
20
+ if (this.topologyWriter === undefined) {
21
+ throw new NotSupportedError("decentralized party preparation requires a topology manager write service");
22
+ }
23
+ const participant = await this.getParticipantIdAsync(new GetParticipantIdRequest(), options);
24
+ return prepareDecentralizedPartyAsync(request, participant, this.topologyWriter, options);
25
+ }
26
+ /** Validates detached decentralized-party signatures before allocation. */
27
+ async finalizeDecentralizedPartyAsync(prepared, signatures, _options) {
28
+ if (prepared.signingRequests.length === 0) {
29
+ throw new ValidationError("decentralized party finalization is missing prepared signing requests");
30
+ }
31
+ const expected = new Map(prepared.signingRequests.map((request) => [request.id, request]));
32
+ const seen = new Set();
33
+ const signaturesByHash = new Map();
34
+ for (const detached of signatures) {
35
+ const signingRequest = expected.get(detached.signingRequestId);
36
+ if (signingRequest === undefined || seen.has(detached.signingRequestId)) {
37
+ throw new ValidationError("decentralized party finalization has unexpected or duplicate signatures");
38
+ }
39
+ else if (detached.result.signature.length === 0) {
40
+ throw new ValidationError("decentralized party finalization has malformed signatures");
41
+ }
42
+ seen.add(detached.signingRequestId);
43
+ const key = toHex(signingRequest.transactionHash);
44
+ const transactionSignatures = signaturesByHash.get(key) ?? [];
45
+ transactionSignatures.push(new ExternalPartySignature({
46
+ format: detached.result.format,
47
+ signature: detached.result.signature,
48
+ signedByFingerprint: signingRequest.publicKeyFingerprint,
49
+ signingAlgorithmSpec: detached.result.signingAlgorithmSpec,
50
+ }));
51
+ signaturesByHash.set(key, transactionSignatures);
52
+ }
53
+ for (const [index, transaction] of prepared.transactions.entries()) {
54
+ const requests = prepared.signingRequests.filter((request) => toHex(request.transactionHash) === toHex(transaction.transactionHash));
55
+ const ownerRequired = index === 0
56
+ ? requests.filter((request) => request.role === "owner").length
57
+ : prepared.ownerThreshold;
58
+ const ownerProvided = requests.filter((request) => request.role === "owner" && seen.has(request.id)).length;
59
+ const partyRequests = requests.filter((request) => request.role === "partySigningKey");
60
+ const partyProvided = partyRequests.filter((request) => seen.has(request.id)).length;
61
+ if (ownerProvided < ownerRequired || partyProvided < partyRequests.length) {
62
+ throw new ValidationError("decentralized party finalization has missing signatures");
63
+ }
64
+ }
65
+ return this.allocateExternalPartyAsync(new AllocateExternalPartyRequest({
66
+ synchronizer: prepared.synchronizer,
67
+ onboardingTransactions: prepared.transactions.map((transaction) => new ExternalPartyOnboardingTransaction({
68
+ transaction: transaction.serializedTransaction,
69
+ signatures: signaturesByHash.get(toHex(transaction.transactionHash)) ?? [],
70
+ })),
71
+ multiHashSignatures: [],
72
+ }), _options);
73
+ }
74
+ /** Creates a decentralized party using the per-key callbacks in the request. */
75
+ async createDecentralizedPartyAsync(request, options) {
76
+ const prepared = await this.prepareDecentralizedPartyAsync(request, options);
77
+ const keys = [...request.owners, ...request.partySigningKeys];
78
+ const signatures = [];
79
+ for (const signingRequest of prepared.signingRequests) {
80
+ const key = keys.find((candidate) => computeFingerprint(candidate) === signingRequest.publicKeyFingerprint);
81
+ if (key?.sign === undefined) {
82
+ throw new ValidationError("decentralized party creation requires a signer for every key");
83
+ }
84
+ signatures.push({
85
+ signingRequestId: signingRequest.id,
86
+ result: await key.sign({
87
+ payload: new Uint8Array(signingRequest.payload),
88
+ kind: "topology-transaction",
89
+ partyId: prepared.partyId,
90
+ publicKeyFingerprint: signingRequest.publicKeyFingerprint,
91
+ role: signingRequest.role,
92
+ transactionHash: new Uint8Array(signingRequest.transactionHash),
93
+ }),
94
+ });
95
+ }
96
+ return this.finalizeDecentralizedPartyAsync(prepared, signatures, options);
97
+ }
7
98
  /** Lists known parties. Supported on JSON and gRPC. */
8
99
  listKnownPartiesAsync(request, options) {
9
100
  return this.transport.listKnownPartiesAsync(request, options);
@@ -28,4 +119,54 @@ export class PartyManagementServiceClient {
28
119
  allocateExternalPartyAsync(request, options) {
29
120
  return this.transport.allocateExternalPartyAsync(request, options);
30
121
  }
122
+ /** Creates an externally controlled party using caller-provided signing. Supported on gRPC. */
123
+ async createExternalPartyAsync(request, options) {
124
+ const generated = await this.generateExternalPartyTopologyAsync(new GenerateExternalPartyTopologyRequest({
125
+ synchronizer: request.synchronizer,
126
+ partyHint: request.partyHint,
127
+ publicKey: request.publicKey,
128
+ localParticipantObservationOnly: request.localParticipantObservationOnly,
129
+ otherConfirmingParticipantUids: [...request.otherConfirmingParticipantUids],
130
+ confirmationThreshold: request.confirmationThreshold,
131
+ observingParticipantUids: [...request.observingParticipantUids],
132
+ }), options);
133
+ const onboardingTransactions = [];
134
+ for (const transaction of generated.topologyTransactions) {
135
+ onboardingTransactions.push(new ExternalPartyOnboardingTransaction({
136
+ transaction,
137
+ signatures: [
138
+ await this.signExternalPartyPayloadAsync(request, transaction, "topology-transaction", generated.partyId, generated.publicKeyFingerprint),
139
+ ],
140
+ }));
141
+ }
142
+ const multiHashSignature = await this.signExternalPartyPayloadAsync(request, generated.multiHash, "multi-hash", generated.partyId, generated.publicKeyFingerprint);
143
+ return this.allocateExternalPartyAsync(new AllocateExternalPartyRequest({
144
+ synchronizer: request.synchronizer,
145
+ onboardingTransactions,
146
+ multiHashSignatures: [multiHashSignature],
147
+ identityProviderId: request.identityProviderId,
148
+ waitForAllocation: request.waitForAllocation,
149
+ userId: request.userId,
150
+ }), options);
151
+ }
152
+ async signExternalPartyPayloadAsync(request, payload, kind, partyId, publicKeyFingerprint) {
153
+ const result = await request.sign({
154
+ payload: new Uint8Array(payload),
155
+ kind,
156
+ partyId,
157
+ publicKeyFingerprint,
158
+ });
159
+ return new ExternalPartySignature({
160
+ format: result.format,
161
+ signature: result.signature,
162
+ signedByFingerprint: publicKeyFingerprint,
163
+ signingAlgorithmSpec: result.signingAlgorithmSpec,
164
+ });
165
+ }
166
+ }
167
+ function toHex(bytes) {
168
+ return [...bytes].map((value) => value.toString(16).padStart(2, "0")).join("");
169
+ }
170
+ function computeFingerprint(key) {
171
+ return computeCantonPublicKeyFingerprint(key.publicKey.keyData, key.publicKey.format);
31
172
  }
@@ -59,6 +59,8 @@ function mapExternalSignatureFormatToRawFormat(signatureFormat) {
59
59
  switch (signatureFormat) {
60
60
  case TopologySignatureFormat.ed25519:
61
61
  return "concat";
62
+ case TopologySignatureFormat.ecDsaSha256:
63
+ return "der";
62
64
  default:
63
65
  return "unspecified";
64
66
  }
@@ -67,6 +69,8 @@ function mapExternalSignatureFormatToAlgorithmSpec(signatureFormat) {
67
69
  switch (signatureFormat) {
68
70
  case TopologySignatureFormat.ed25519:
69
71
  return "ed25519";
72
+ case TopologySignatureFormat.ecDsaSha256:
73
+ return "ecDsaSha256";
70
74
  default:
71
75
  return "unspecified";
72
76
  }
@@ -0,0 +1,20 @@
1
+ import { CampaignMetrics } from "./campaign-metrics.js";
2
+ export interface CampaignReplayArtifact {
3
+ readonly actions: readonly Readonly<Record<string, unknown>>[];
4
+ readonly fingerprint: string;
5
+ readonly metrics: CampaignMetrics;
6
+ readonly numRuns: number;
7
+ readonly numShrinks: number;
8
+ readonly schemaVersion: 1;
9
+ readonly seed?: number;
10
+ readonly counterexamplePath?: string;
11
+ readonly [key: string]: unknown;
12
+ }
13
+ export declare function createCampaignFingerprint(value: unknown): string;
14
+ export declare function serializeCampaignReplayArtifact(artifact: CampaignReplayArtifact): string;
15
+ export declare function selectCampaignCounterexampleTrace<T>(details: {
16
+ readonly failed: boolean;
17
+ readonly counterexampleKey?: string;
18
+ }, traces: ReadonlyMap<string, T>): T;
19
+ export declare function writeCampaignReplayArtifactAsync(filename: string, artifact: CampaignReplayArtifact): Promise<void>;
20
+ export declare function loadCampaignReplayArtifactAsync(filename: string, fingerprint: string): Promise<CampaignReplayArtifact>;
@@ -0,0 +1,147 @@
1
+ import { createHash } from "node:crypto";
2
+ import { chmod, lstat, mkdir, open, readFile } from "node:fs/promises";
3
+ import { dirname, parse, relative, resolve, sep } from "node:path";
4
+ export function createCampaignFingerprint(value) {
5
+ return createHash("sha256")
6
+ .update(canonicalCampaignJson(value))
7
+ .digest("hex");
8
+ }
9
+ export function serializeCampaignReplayArtifact(artifact) {
10
+ return `${JSON.stringify({
11
+ schemaVersion: artifact.schemaVersion,
12
+ fingerprint: artifact.fingerprint,
13
+ actions: artifact.actions.map((action) => ({
14
+ ...(typeof action.targetKey === "string"
15
+ ? { targetKey: action.targetKey }
16
+ : {}),
17
+ ...(typeof action.actor === "string" ? { actor: action.actor } : {}),
18
+ ...(typeof action.outcome === "string"
19
+ ? { outcome: action.outcome }
20
+ : {}),
21
+ })),
22
+ metrics: artifact.metrics,
23
+ numRuns: artifact.numRuns,
24
+ numShrinks: artifact.numShrinks,
25
+ ...(artifact.seed === undefined ? {} : { seed: artifact.seed }),
26
+ ...(artifact.counterexamplePath === undefined
27
+ ? {}
28
+ : { counterexamplePath: artifact.counterexamplePath }),
29
+ })}\n`;
30
+ }
31
+ export function selectCampaignCounterexampleTrace(details, traces) {
32
+ if (!details.failed || details.counterexampleKey === undefined) {
33
+ throw new Error("Invariant campaign did not produce a counterexample.");
34
+ }
35
+ const trace = traces.get(details.counterexampleKey);
36
+ if (trace === undefined) {
37
+ throw new Error("Final invariant campaign counterexample has no trace.");
38
+ }
39
+ return trace;
40
+ }
41
+ export async function writeCampaignReplayArtifactAsync(filename, artifact) {
42
+ const destination = resolve(filename);
43
+ await ensureSecureDirectoryAsync(dirname(destination));
44
+ const handle = await open(destination, "wx", 0o600);
45
+ try {
46
+ await handle.writeFile(serializeCampaignReplayArtifact(artifact), "utf8");
47
+ await handle.sync();
48
+ }
49
+ finally {
50
+ await handle.close();
51
+ }
52
+ }
53
+ export async function loadCampaignReplayArtifactAsync(filename, fingerprint) {
54
+ const artifact = JSON.parse(await readFile(resolve(filename), "utf8"));
55
+ if (!isCampaignReplayArtifact(artifact)) {
56
+ throw new Error("Invariant campaign replay artifact has an invalid schema.");
57
+ }
58
+ else if (artifact.fingerprint !== fingerprint) {
59
+ throw new Error("Invariant campaign replay artifact fingerprint does not match.");
60
+ }
61
+ return artifact;
62
+ }
63
+ function canonicalCampaignJson(value) {
64
+ return JSON.stringify(sortJsonValue(value));
65
+ }
66
+ function sortJsonValue(value) {
67
+ if (Array.isArray(value)) {
68
+ return value.map(sortJsonValue);
69
+ }
70
+ else if (value !== null && typeof value === "object") {
71
+ return Object.fromEntries(Object.entries(value)
72
+ .sort(([left], [right]) => left.localeCompare(right))
73
+ .map(([key, nested]) => [key, sortJsonValue(nested)]));
74
+ }
75
+ return value;
76
+ }
77
+ function isCampaignReplayArtifact(value) {
78
+ return value !== null
79
+ && typeof value === "object"
80
+ && value.schemaVersion === 1
81
+ && typeof value.fingerprint === "string"
82
+ && Array.isArray(value.actions)
83
+ && value.actions.every(isReplayAction)
84
+ && isCampaignMetrics(value.metrics)
85
+ && isPositiveSafeInteger(value.numRuns)
86
+ && isNonNegativeSafeInteger(value.numShrinks);
87
+ }
88
+ function isReplayAction(value) {
89
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
90
+ return false;
91
+ }
92
+ const action = value;
93
+ const allowedKeys = new Set(["actor", "outcome", "targetKey"]);
94
+ return Object.entries(action).every(([key, field]) => allowedKeys.has(key) && typeof field === "string");
95
+ }
96
+ function isPositiveSafeInteger(value) {
97
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
98
+ }
99
+ function isNonNegativeSafeInteger(value) {
100
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
101
+ }
102
+ function isCampaignMetrics(value) {
103
+ if (value === null || typeof value !== "object") {
104
+ return false;
105
+ }
106
+ const candidate = value;
107
+ return isMetricGroup(candidate.byActor) && isMetricGroup(candidate.byTarget);
108
+ }
109
+ function isMetricGroup(value) {
110
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
111
+ return false;
112
+ }
113
+ return Object.values(value).every((outcomes) => outcomes !== null
114
+ && typeof outcomes === "object"
115
+ && !Array.isArray(outcomes)
116
+ && Object.values(outcomes).every((count) => typeof count === "number" && Number.isSafeInteger(count) && count >= 0));
117
+ }
118
+ async function ensureSecureDirectoryAsync(directory) {
119
+ const absoluteDirectory = resolve(directory);
120
+ const root = parse(absoluteDirectory).root;
121
+ const segments = relative(root, absoluteDirectory).split(sep).filter(Boolean);
122
+ let current = root;
123
+ for (const segment of segments) {
124
+ current = resolve(current, segment);
125
+ try {
126
+ const entry = await lstat(current);
127
+ if (entry.isSymbolicLink()) {
128
+ throw new Error(`Invariant campaign artifact parent is a symlink: ${current}`);
129
+ }
130
+ else if (!entry.isDirectory()) {
131
+ throw new Error(`Invariant campaign artifact parent is not a directory: ${current}`);
132
+ }
133
+ }
134
+ catch (error) {
135
+ if (!isNotFoundError(error)) {
136
+ throw error;
137
+ }
138
+ await mkdir(current, { mode: 0o700 });
139
+ }
140
+ }
141
+ await chmod(absoluteDirectory, 0o700);
142
+ }
143
+ function isNotFoundError(error) {
144
+ return typeof error === "object"
145
+ && error !== null
146
+ && error.code === "ENOENT";
147
+ }
@@ -0,0 +1,9 @@
1
+ import { CampaignHandler } from "../handlers/handler.js";
2
+ import { CampaignInvariant, CampaignRuntime, CampaignTarget, InvariantCampaign, InvariantCampaignConfig } from "./campaign-types.js";
3
+ export declare function defineInvariantCampaign<Model = unknown, Ghost = unknown>(init: {
4
+ readonly runtime: CampaignRuntime;
5
+ readonly config: InvariantCampaignConfig;
6
+ readonly handlers?: readonly CampaignHandler[];
7
+ readonly targets: readonly CampaignTarget[];
8
+ readonly invariants: readonly CampaignInvariant<Model, Ghost>[];
9
+ }): InvariantCampaign<Model, Ghost>;