@distrohelena/canton-typescript-sdk 0.1.4 → 0.1.5

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 (25) hide show
  1. package/dist/client/service-registry.js +1 -1
  2. package/dist/core/signing/sign-command-request.d.ts +4 -0
  3. package/dist/core/signing/sign-command-request.js +4 -0
  4. package/dist/core/signing/sign-command-result.d.ts +2 -0
  5. package/dist/core/signing/sign-command-result.js +9 -0
  6. package/dist/core/transports/transport.interface.d.ts +2 -2
  7. package/dist/core/types/commands/create-and-exercise-command.js +1 -1
  8. package/dist/core/types/commands/exercise-by-key-command.js +2 -2
  9. package/dist/core/types/commands/exercise-command.js +2 -2
  10. package/dist/core/types/requests/submit-command-request.d.ts +2 -0
  11. package/dist/core/types/requests/submit-command-request.js +2 -0
  12. package/dist/services/commands/command-payload-builder.js +3 -3
  13. package/dist/services/commands/command-submission-pipeline.js +1 -7
  14. package/dist/transports/grpc/grpc-channel-factory.d.ts +4 -0
  15. package/dist/transports/grpc/grpc-channel-factory.js +11 -0
  16. package/dist/transports/grpc/grpc-transport.d.ts +2 -2
  17. package/dist/transports/grpc/grpc-transport.js +40 -3
  18. package/dist/transports/grpc/mappers/commands-mapper.d.ts +10 -2
  19. package/dist/transports/grpc/mappers/commands-mapper.js +12 -12
  20. package/dist/transports/grpc/mappers/interactive-command-mapper.d.ts +15 -0
  21. package/dist/transports/grpc/mappers/interactive-command-mapper.js +54 -0
  22. package/dist/transports/json/json-transport.d.ts +2 -2
  23. package/dist/transports/json/json-transport.js +2 -2
  24. package/dist/transports/json/mappers/commands-mapper.js +3 -3
  25. package/package.json +1 -1
@@ -412,7 +412,7 @@ class PlaceholderTransport {
412
412
  this.throwIfDisposed();
413
413
  throw new TransportError("CommandCompletionService.GetCompletions is not available yet");
414
414
  }
415
- async submitCommandAsync(_request, _signed, _options) {
415
+ async submitCommandAsync(_request, _signer, _options) {
416
416
  this.throwIfDisposed();
417
417
  throw new TransportError("command submission is not available yet");
418
418
  }
@@ -1,8 +1,12 @@
1
1
  export declare class SignCommandRequest {
2
2
  readonly payload: Uint8Array;
3
3
  readonly keyId?: string;
4
+ readonly party?: string;
5
+ readonly algorithmHint?: string;
4
6
  constructor(init: {
5
7
  payload: Uint8Array;
6
8
  keyId?: string;
9
+ party?: string;
10
+ algorithmHint?: string;
7
11
  });
8
12
  }
@@ -1,8 +1,12 @@
1
1
  export class SignCommandRequest {
2
2
  payload;
3
3
  keyId;
4
+ party;
5
+ algorithmHint;
4
6
  constructor(init) {
5
7
  this.payload = init.payload;
6
8
  this.keyId = init.keyId;
9
+ this.party = init.party;
10
+ this.algorithmHint = init.algorithmHint;
7
11
  }
8
12
  }
@@ -1,10 +1,12 @@
1
1
  export declare class SignCommandResult {
2
2
  readonly algorithm: string;
3
3
  readonly signature: Uint8Array;
4
+ readonly signedBy: string;
4
5
  readonly keyId?: string;
5
6
  constructor(init: {
6
7
  algorithm: string;
7
8
  signature: Uint8Array;
9
+ signedBy: string;
8
10
  keyId?: string;
9
11
  });
10
12
  }
@@ -1,10 +1,19 @@
1
+ import { ValidationError } from "../errors/validation-error.js";
1
2
  export class SignCommandResult {
2
3
  algorithm;
3
4
  signature;
5
+ signedBy;
4
6
  keyId;
5
7
  constructor(init) {
8
+ if (init.signature.length === 0) {
9
+ throw new ValidationError("command signatures require signature bytes");
10
+ }
11
+ else if (!init.signedBy) {
12
+ throw new ValidationError("command signatures require signedBy");
13
+ }
6
14
  this.algorithm = init.algorithm;
7
15
  this.signature = init.signature;
16
+ this.signedBy = init.signedBy;
8
17
  this.keyId = init.keyId;
9
18
  }
10
19
  }
@@ -185,7 +185,7 @@ import { CompletionObserver } from "../../services/command-completion/completion
185
185
  import { CommitmentChunkObserver } from "../../services/participant-inspection/commitment-chunk-observer.interface.js";
186
186
  import { ContractObserver } from "../../services/contracts/contract-observer.interface.js";
187
187
  import { TransactionObserver } from "../../services/events/transaction-observer.interface.js";
188
- import { SignCommandResult } from "../signing/sign-command-result.js";
188
+ import { ICommandSigner } from "../signing/command-signer.interface.js";
189
189
  import { RequestOptions } from "../types/request-options.js";
190
190
  import { SubmitCommandRequest } from "../types/requests/submit-command-request.js";
191
191
  export interface ITransport {
@@ -380,5 +380,5 @@ export interface ITransport {
380
380
  * Submits a command.
381
381
  * Supported on JSON and gRPC. External signing is gRPC-only.
382
382
  */
383
- submitCommandAsync(request: SubmitCommandRequest, signed?: SignCommandResult, options?: RequestOptions): Promise<SubmitCommandResponse>;
383
+ submitCommandAsync(request: SubmitCommandRequest, signer?: ICommandSigner, options?: RequestOptions): Promise<SubmitCommandResponse>;
384
384
  }
@@ -8,7 +8,7 @@ export class CreateAndExerciseCommand {
8
8
  if (!init.templateId) {
9
9
  throw new ValidationError("create-and-exercise commands require a templateId");
10
10
  }
11
- if (!init.choice) {
11
+ else if (!init.choice) {
12
12
  throw new ValidationError("create-and-exercise commands require a choice");
13
13
  }
14
14
  this.templateId = init.templateId;
@@ -8,10 +8,10 @@ export class ExerciseByKeyCommand {
8
8
  if (!init.templateId) {
9
9
  throw new ValidationError("exercise-by-key commands require a templateId");
10
10
  }
11
- if (init.contractKey === undefined) {
11
+ else if (init.contractKey === undefined) {
12
12
  throw new ValidationError("exercise-by-key commands require a contractKey");
13
13
  }
14
- if (!init.choice) {
14
+ else if (!init.choice) {
15
15
  throw new ValidationError("exercise-by-key commands require a choice");
16
16
  }
17
17
  this.templateId = init.templateId;
@@ -8,10 +8,10 @@ export class ExerciseCommand {
8
8
  if (!init.templateId) {
9
9
  throw new ValidationError("exercise commands require a templateId");
10
10
  }
11
- if (!init.contractId) {
11
+ else if (!init.contractId) {
12
12
  throw new ValidationError("exercise commands require a contractId");
13
13
  }
14
- if (!init.choice) {
14
+ else if (!init.choice) {
15
15
  throw new ValidationError("exercise commands require a choice");
16
16
  }
17
17
  this.templateId = init.templateId;
@@ -1,11 +1,13 @@
1
1
  import { LedgerCommand } from "../commands/ledger-command.js";
2
2
  export declare class SubmitCommandRequest {
3
3
  readonly applicationId: string;
4
+ readonly userId?: string;
4
5
  readonly actAs: readonly string[];
5
6
  readonly readAs: readonly string[];
6
7
  readonly command: LedgerCommand;
7
8
  constructor(init: {
8
9
  applicationId: string;
10
+ userId?: string;
9
11
  actAs: readonly string[];
10
12
  readAs?: readonly string[];
11
13
  command: LedgerCommand;
@@ -1,6 +1,7 @@
1
1
  import { ValidationError } from "../../errors/validation-error.js";
2
2
  export class SubmitCommandRequest {
3
3
  applicationId;
4
+ userId;
4
5
  actAs;
5
6
  readAs;
6
7
  command;
@@ -9,6 +10,7 @@ export class SubmitCommandRequest {
9
10
  throw new ValidationError("submit requests require at least one actAs party");
10
11
  }
11
12
  this.applicationId = init.applicationId;
13
+ this.userId = init.userId;
12
14
  this.actAs = init.actAs;
13
15
  this.readAs = init.readAs ?? [];
14
16
  this.command = init.command;
@@ -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
  }
@@ -20,6 +20,7 @@ import { IPartyManagementServiceClient } from "./generated/canton/com/daml/ledge
20
20
  import { IUserManagementServiceClient } from "./generated/canton/com/daml/ledger/api/v2/admin/user_management_service.client.js";
21
21
  import { IVersionServiceClient } from "./generated/canton/com/daml/ledger/api/v2/version_service.client.js";
22
22
  import { ICommandServiceClient } from "./generated/canton/com/daml/ledger/api/v2/command_service.client.js";
23
+ import { IInteractiveSubmissionServiceClient } from "./generated/canton/com/daml/ledger/api/v2/interactive/interactive_submission_service.client.js";
23
24
  import { ICommandCompletionServiceClient } from "./generated/canton/com/daml/ledger/api/v2/command_completion_service.client.js";
24
25
  import { IContractServiceClient } from "./generated/canton/com/daml/ledger/api/v2/contract_service.client.js";
25
26
  import { IEventQueryServiceClient } from "./generated/canton/com/daml/ledger/api/v2/event_query_service.client.js";
@@ -121,6 +122,8 @@ export interface GrpcOperations {
121
122
  getUpdateByHashAsync?(request: unknown, options?: RequestOptions): Promise<unknown>;
122
123
  getUpdatesPageAsync?(request: unknown, options?: RequestOptions): Promise<unknown>;
123
124
  getCompletionsAsync?(request: unknown, options?: RequestOptions): Promise<unknown>;
125
+ prepareSubmissionAsync?(request: unknown, options?: RequestOptions): Promise<unknown>;
126
+ executeSubmissionAndWaitAsync?(request: unknown, options?: RequestOptions): Promise<unknown>;
124
127
  submitCommandAsync(request: unknown, options?: RequestOptions): Promise<unknown>;
125
128
  }
126
129
  export interface GrpcOperationDependencies {
@@ -150,6 +153,7 @@ export interface GrpcOperationDependencies {
150
153
  stateServiceClient?: Pick<IStateServiceClient, "getActiveContractsPage" | "getConnectedSynchronizers" | "getLedgerEnd" | "getLatestPrunedOffsets">;
151
154
  updateServiceClient?: Pick<IUpdateServiceClient, "getUpdates" | "getUpdateByOffset" | "getUpdateById" | "getUpdateByHash" | "getUpdatesPage">;
152
155
  commandCompletionServiceClient?: Pick<ICommandCompletionServiceClient, "getCompletions">;
156
+ interactiveSubmissionServiceClient?: Pick<IInteractiveSubmissionServiceClient, "prepareSubmission" | "executeSubmissionAndWait">;
153
157
  commandServiceClient?: Pick<ICommandServiceClient, "submitAndWait">;
154
158
  }
155
159
  export declare function createGrpcOperations(options: CantonClientOptions, endpoint: string, grpcChannelSecurity: GrpcChannelSecurity, dependencies?: GrpcOperationDependencies): GrpcOperations;
@@ -20,6 +20,7 @@ import { PartyManagementServiceClient, } from "./generated/canton/com/daml/ledge
20
20
  import { UserManagementServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/admin/user_management_service.client.js";
21
21
  import { VersionServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/version_service.client.js";
22
22
  import { CommandServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/command_service.client.js";
23
+ import { InteractiveSubmissionServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/interactive/interactive_submission_service.client.js";
23
24
  import { CommandCompletionServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/command_completion_service.client.js";
24
25
  import { ContractServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/contract_service.client.js";
25
26
  import { EventQueryServiceClient, } from "./generated/canton/com/daml/ledger/api/v2/event_query_service.client.js";
@@ -85,6 +86,8 @@ export function createGrpcOperations(options, endpoint, grpcChannelSecurity, dep
85
86
  const updateServiceClient = dependencies.updateServiceClient ?? new UpdateServiceClient(rpcTransport);
86
87
  const commandCompletionServiceClient = dependencies.commandCompletionServiceClient
87
88
  ?? new CommandCompletionServiceClient(rpcTransport);
89
+ const interactiveSubmissionServiceClient = dependencies.interactiveSubmissionServiceClient
90
+ ?? new InteractiveSubmissionServiceClient(rpcTransport);
88
91
  const commandServiceClient = dependencies.commandServiceClient
89
92
  ?? new CommandServiceClient(rpcTransport);
90
93
  return {
@@ -459,6 +462,14 @@ export function createGrpcOperations(options, endpoint, grpcChannelSecurity, dep
459
462
  const callOptions = await buildCallOptionsForLedgerSurfaceAsync(options, requestOptions);
460
463
  return await unwrapUnaryResponse(commandServiceClient.submitAndWait(request, callOptions));
461
464
  },
465
+ async prepareSubmissionAsync(request, requestOptions) {
466
+ const callOptions = await buildCallOptionsForLedgerSurfaceAsync(options, requestOptions);
467
+ return await unwrapUnaryResponse(interactiveSubmissionServiceClient.prepareSubmission(request, callOptions));
468
+ },
469
+ async executeSubmissionAndWaitAsync(request, requestOptions) {
470
+ const callOptions = await buildCallOptionsForLedgerSurfaceAsync(options, requestOptions);
471
+ return await unwrapUnaryResponse(interactiveSubmissionServiceClient.executeSubmissionAndWait(request, callOptions));
472
+ },
462
473
  };
463
474
  }
464
475
  async function buildCallOptionsForLedgerSurfaceAsync(options, requestOptions) {
@@ -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 { SignCommandResult } from "../../core/signing/sign-command-result.js";
87
+ import { 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, signed?: SignCommandResult, options?: RequestOptions): Promise<SubmitCommandResponse>;
278
+ submitCommandAsync(request: SubmitCommandRequest, signer?: ICommandSigner, options?: RequestOptions): Promise<SubmitCommandResponse>;
279
279
  private throwIfDisposed;
280
280
  private throwPartyTopologyReadCompatibilityError;
281
281
  private isProtobufDeserializationFailure;
@@ -1,3 +1,6 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { ValidationError } from "../../core/errors/validation-error.js";
3
+ import { SignCommandRequest } from "../../core/signing/sign-command-request.js";
1
4
  import { AllocatePartyResponse as SdkAllocatePartyResponse } from "../../core/types/responses/allocate-party-response.js";
2
5
  import { GetActiveContractsPageResponse } from "../../core/types/responses/get-active-contracts-page-response.js";
3
6
  import { GetLedgerApiVersionResponse as SdkGetLedgerApiVersionResponse } from "../../core/types/responses/get-ledger-api-version-response.js";
@@ -8,6 +11,7 @@ import { TransportError } from "../../core/errors/transport-error.js";
8
11
  import { PackageFormat } from "../../core/types/package-format.js";
9
12
  import { createGrpcOperations, } from "./grpc-channel-factory.js";
10
13
  import { mapGrpcSubmitCommand, mapGrpcSubmitCommandRequest, } from "./mappers/commands-mapper.js";
14
+ import { mapGrpcExecuteSubmissionAndWaitRequest, mapGrpcInteractiveSubmitCommand, mapGrpcPrepareSubmissionRequest, } from "./mappers/interactive-command-mapper.js";
11
15
  import { mapGrpcGetContract, mapGrpcGetContractRequest, mapGrpcQueryContracts, mapGrpcQueryContractsRequest, } from "./mappers/contracts-mapper.js";
12
16
  import { mapGrpcCompletionStreamResponse, mapGrpcGetCompletionsRequest, } from "./mappers/command-completion-mapper.js";
13
17
  import { mapGrpcGetCommandStatus, mapGrpcGetCommandStatusRequest, } from "./mappers/command-inspection-mapper.js";
@@ -571,10 +575,43 @@ export class GrpcTransport {
571
575
  await observer.nextAsync(mapGrpcCompletionStreamResponse(response));
572
576
  }
573
577
  }
574
- async submitCommandAsync(request, signed, options) {
578
+ async submitCommandAsync(request, signer, options) {
575
579
  this.throwIfDisposed();
576
- const payload = await this.operations.submitCommandAsync(mapGrpcSubmitCommandRequest(request, signed), options);
577
- return mapGrpcSubmitCommand(payload);
580
+ if (!signer) {
581
+ const payload = await this.operations.submitCommandAsync(mapGrpcSubmitCommandRequest(request), options);
582
+ return mapGrpcSubmitCommand(payload);
583
+ }
584
+ if (request.actAs.length !== 1) {
585
+ throw new ValidationError("interactive gRPC command signing currently requires exactly one actAs party");
586
+ }
587
+ if (!this.operations.prepareSubmissionAsync) {
588
+ throw new NotSupportedError("interactive gRPC command signing is not available on this transport");
589
+ }
590
+ if (!this.operations.executeSubmissionAndWaitAsync) {
591
+ throw new NotSupportedError("interactive gRPC command signing is not available on this transport");
592
+ }
593
+ const commandId = randomUUID();
594
+ const submissionId = randomUUID();
595
+ const prepared = await this.operations.prepareSubmissionAsync(mapGrpcPrepareSubmissionRequest(request, commandId), options);
596
+ if (!prepared.preparedTransaction) {
597
+ throw new ValidationError("interactive prepare submission did not return a preparedTransaction");
598
+ }
599
+ else if (prepared.preparedTransactionHash.length === 0) {
600
+ throw new ValidationError("interactive prepare submission did not return a preparedTransactionHash");
601
+ }
602
+ const signerResult = await signer.signAsync(new SignCommandRequest({
603
+ payload: prepared.preparedTransactionHash,
604
+ party: request.actAs[0],
605
+ algorithmHint: "ed25519",
606
+ }));
607
+ const executed = await this.operations.executeSubmissionAndWaitAsync(mapGrpcExecuteSubmissionAndWaitRequest({
608
+ request,
609
+ preparedTransaction: prepared.preparedTransaction,
610
+ hashingSchemeVersion: prepared.hashingSchemeVersion,
611
+ submissionId,
612
+ signerResult,
613
+ }), options);
614
+ return mapGrpcInteractiveSubmitCommand(executed);
578
615
  }
579
616
  throwIfDisposed() {
580
617
  if (this.disposed) {
@@ -1,10 +1,18 @@
1
- import { SignCommandResult } from "../../../core/signing/sign-command-result.js";
1
+ import { CreateCommand } from "../../../core/types/commands/create-command.js";
2
+ import { LedgerCommand } from "../../../core/types/commands/ledger-command.js";
2
3
  import { SubmitCommandRequest } from "../../../core/types/requests/submit-command-request.js";
3
4
  import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
5
+ import { Command } from "../generated/canton/com/daml/ledger/api/v2/commands.js";
4
6
  import { SubmitAndWaitRequest, SubmitAndWaitResponse } from "../generated/canton/com/daml/ledger/api/v2/command_service.js";
5
- export declare function mapGrpcSubmitCommandRequest(request: SubmitCommandRequest, _signed?: SignCommandResult): SubmitAndWaitRequest;
7
+ import { Identifier, Record as GrpcRecord, Value } from "../generated/canton/com/daml/ledger/api/v2/value.js";
8
+ export declare function mapGrpcSubmitCommandRequest(request: SubmitCommandRequest): SubmitAndWaitRequest;
6
9
  export declare function mapGrpcSubmitCommand(payload: {
7
10
  commandId?: string;
8
11
  transactionId?: string;
9
12
  updateId?: string;
10
13
  } | SubmitAndWaitResponse): SubmitCommandResponse;
14
+ export declare function mapGrpcLedgerCommand(command: LedgerCommand): Command;
15
+ export declare function mapGrpcCreateCommand(command: CreateCommand): Command;
16
+ export declare function mapRecord(payload: Record<string, unknown>): GrpcRecord;
17
+ export declare function mapValue(value: unknown): Value;
18
+ export declare function parseTemplateIdentifier(templateId: string): Identifier;
@@ -5,13 +5,13 @@ import { CreateCommand } from "../../../core/types/commands/create-command.js";
5
5
  import { ExerciseByKeyCommand } from "../../../core/types/commands/exercise-by-key-command.js";
6
6
  import { ExerciseCommand } from "../../../core/types/commands/exercise-command.js";
7
7
  import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
8
- export function mapGrpcSubmitCommandRequest(request, _signed) {
8
+ export function mapGrpcSubmitCommandRequest(request) {
9
9
  return {
10
10
  commands: {
11
11
  workflowId: "",
12
- userId: "",
12
+ userId: request.userId ?? "",
13
13
  commandId: randomUUID(),
14
- commands: [mapCommand(request.command)],
14
+ commands: [mapGrpcLedgerCommand(request.command)],
15
15
  deduplicationPeriod: {
16
16
  oneofKind: undefined,
17
17
  },
@@ -33,11 +33,11 @@ export function mapGrpcSubmitCommand(payload) {
33
33
  : payload.updateId,
34
34
  });
35
35
  }
36
- function mapCommand(command) {
36
+ export function mapGrpcLedgerCommand(command) {
37
37
  if (command instanceof CreateCommand) {
38
- return mapCreateCommand(command);
38
+ return mapGrpcCreateCommand(command);
39
39
  }
40
- if (command instanceof ExerciseCommand) {
40
+ else if (command instanceof ExerciseCommand) {
41
41
  return {
42
42
  command: {
43
43
  oneofKind: "exercise",
@@ -50,7 +50,7 @@ function mapCommand(command) {
50
50
  },
51
51
  };
52
52
  }
53
- if (command instanceof ExerciseByKeyCommand) {
53
+ else if (command instanceof ExerciseByKeyCommand) {
54
54
  return {
55
55
  command: {
56
56
  oneofKind: "exerciseByKey",
@@ -63,7 +63,7 @@ function mapCommand(command) {
63
63
  },
64
64
  };
65
65
  }
66
- if (command instanceof CreateAndExerciseCommand) {
66
+ else if (command instanceof CreateAndExerciseCommand) {
67
67
  return {
68
68
  command: {
69
69
  oneofKind: "createAndExercise",
@@ -78,7 +78,7 @@ function mapCommand(command) {
78
78
  }
79
79
  throw new ValidationError("unsupported submit command type");
80
80
  }
81
- function mapCreateCommand(command) {
81
+ export function mapGrpcCreateCommand(command) {
82
82
  return {
83
83
  command: {
84
84
  oneofKind: "create",
@@ -89,7 +89,7 @@ function mapCreateCommand(command) {
89
89
  },
90
90
  };
91
91
  }
92
- function mapRecord(payload) {
92
+ export function mapRecord(payload) {
93
93
  return {
94
94
  fields: Object.entries(payload).map(([label, value]) => ({
95
95
  label,
@@ -97,7 +97,7 @@ function mapRecord(payload) {
97
97
  })),
98
98
  };
99
99
  }
100
- function mapValue(value) {
100
+ export function mapValue(value) {
101
101
  if (value === null || value === undefined) {
102
102
  return {
103
103
  sum: {
@@ -154,7 +154,7 @@ function mapValue(value) {
154
154
  },
155
155
  };
156
156
  }
157
- function parseTemplateIdentifier(templateId) {
157
+ export function parseTemplateIdentifier(templateId) {
158
158
  const parts = templateId.split(":");
159
159
  if (parts.length === 2) {
160
160
  return {
@@ -0,0 +1,15 @@
1
+ import { SignCommandResult } from "../../../core/signing/sign-command-result.js";
2
+ import { SubmitCommandRequest } from "../../../core/types/requests/submit-command-request.js";
3
+ import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
4
+ import { Signature } from "../generated/canton/com/daml/ledger/api/v2/crypto.js";
5
+ import { ExecuteSubmissionAndWaitRequest, ExecuteSubmissionAndWaitResponse, HashingSchemeVersion, PrepareSubmissionRequest, PreparedTransaction } from "../generated/canton/com/daml/ledger/api/v2/interactive/interactive_submission_service.js";
6
+ export declare function mapGrpcPrepareSubmissionRequest(request: SubmitCommandRequest, commandId: string): PrepareSubmissionRequest;
7
+ export declare function mapGrpcExecuteSubmissionAndWaitRequest(init: {
8
+ request: SubmitCommandRequest;
9
+ preparedTransaction: PreparedTransaction;
10
+ hashingSchemeVersion: HashingSchemeVersion;
11
+ submissionId: string;
12
+ signerResult: SignCommandResult;
13
+ }): ExecuteSubmissionAndWaitRequest;
14
+ export declare function mapGrpcInteractiveSubmitCommand(payload: ExecuteSubmissionAndWaitResponse): SubmitCommandResponse;
15
+ export declare function mapGrpcSignature(result: SignCommandResult): Signature;
@@ -0,0 +1,54 @@
1
+ import { ValidationError } from "../../../core/errors/validation-error.js";
2
+ import { SubmitCommandResponse } from "../../../core/types/responses/submit-command-response.js";
3
+ import { SignatureFormat, SigningAlgorithmSpec, } from "../generated/canton/com/daml/ledger/api/v2/crypto.js";
4
+ import { mapGrpcLedgerCommand } from "./commands-mapper.js";
5
+ export function mapGrpcPrepareSubmissionRequest(request, commandId) {
6
+ return {
7
+ userId: request.userId ?? "",
8
+ commandId,
9
+ commands: [mapGrpcLedgerCommand(request.command)],
10
+ actAs: [...request.actAs],
11
+ readAs: [...request.readAs],
12
+ disclosedContracts: [],
13
+ synchronizerId: "",
14
+ packageIdSelectionPreference: [],
15
+ prefetchContractKeys: [],
16
+ verboseHashing: false,
17
+ };
18
+ }
19
+ export function mapGrpcExecuteSubmissionAndWaitRequest(init) {
20
+ return {
21
+ preparedTransaction: init.preparedTransaction,
22
+ partySignatures: {
23
+ signatures: [
24
+ {
25
+ party: init.request.actAs[0] ?? "",
26
+ signatures: [mapGrpcSignature(init.signerResult)],
27
+ },
28
+ ],
29
+ },
30
+ deduplicationPeriod: {
31
+ oneofKind: undefined,
32
+ },
33
+ submissionId: init.submissionId,
34
+ userId: init.request.userId ?? "",
35
+ hashingSchemeVersion: init.hashingSchemeVersion,
36
+ };
37
+ }
38
+ export function mapGrpcInteractiveSubmitCommand(payload) {
39
+ return new SubmitCommandResponse({
40
+ transactionId: payload.updateId,
41
+ });
42
+ }
43
+ export function mapGrpcSignature(result) {
44
+ const algorithm = result.algorithm.toLowerCase();
45
+ if (algorithm === "ed25519") {
46
+ return {
47
+ format: SignatureFormat.CONCAT,
48
+ signature: result.signature,
49
+ signedBy: result.signedBy,
50
+ signingAlgorithmSpec: SigningAlgorithmSpec.ED25519,
51
+ };
52
+ }
53
+ throw new ValidationError(`unsupported gRPC command signing algorithm '${result.algorithm}'`);
54
+ }
@@ -63,7 +63,6 @@ import { ParticipantListPackagesRequest } from "../../core/types/requests/partic
63
63
  import { SubmitCommandRequest } from "../../core/types/requests/submit-command-request.js";
64
64
  import { TrafficControlStateRequest } from "../../core/types/requests/traffic-control-state-request.js";
65
65
  import { UploadDarFileRequest } from "../../core/types/requests/upload-dar-file-request.js";
66
- import { SignCommandResult } from "../../core/signing/sign-command-result.js";
67
66
  import { AllocatePartyResponse } from "../../core/types/responses/allocate-party-response.js";
68
67
  import { AllocateExternalPartyResponse } from "../../core/types/responses/allocate-external-party-response.js";
69
68
  import { AddPartyAsyncResponse } from "../../core/types/responses/add-party-async-response.js";
@@ -127,6 +126,7 @@ import { SubmitCommandResponse } from "../../core/types/responses/submit-command
127
126
  import { TrafficControlStateResponse } from "../../core/types/responses/traffic-control-state-response.js";
128
127
  import { UploadDarFileResponse } from "../../core/types/responses/upload-dar-file-response.js";
129
128
  import { ITransport } from "../../core/transports/transport.interface.js";
129
+ import { ICommandSigner } from "../../core/signing/command-signer.interface.js";
130
130
  import { RequestOptions } from "../../core/types/request-options.js";
131
131
  import { IJsonHttpClient } from "./json-http-client.js";
132
132
  import { CompletionObserver } from "../../services/command-completion/completion-observer.interface.js";
@@ -233,6 +233,6 @@ export declare class JsonTransport implements ITransport {
233
233
  getUpdateByHashAsync(_request: GetUpdateByHashRequest, _options?: RequestOptions): Promise<GetUpdateByHashResponse>;
234
234
  getUpdatesPageAsync(_request: GetUpdatesPageRequest, _options?: RequestOptions): Promise<GetUpdatesPageResponse>;
235
235
  getCompletionsAsync(_request: GetCompletionsRequest, _observer: CompletionObserver, _options?: RequestOptions): Promise<void>;
236
- submitCommandAsync(request: SubmitCommandRequest, signed?: SignCommandResult, options?: RequestOptions): Promise<SubmitCommandResponse>;
236
+ submitCommandAsync(request: SubmitCommandRequest, signer?: ICommandSigner, options?: RequestOptions): Promise<SubmitCommandResponse>;
237
237
  private throwIfDisposed;
238
238
  }
@@ -453,9 +453,9 @@ export class JsonTransport {
453
453
  this.throwIfDisposed();
454
454
  throw new NotSupportedError("CommandCompletionService.GetCompletions is not supported by json transport");
455
455
  }
456
- async submitCommandAsync(request, signed, options) {
456
+ async submitCommandAsync(request, signer, options) {
457
457
  this.throwIfDisposed();
458
- if (signed) {
458
+ if (signer) {
459
459
  throw new NotSupportedError("command signing is not supported by json transport");
460
460
  }
461
461
  const payload = await this.httpClient.postAsync("/v2/commands/submit-and-wait", mapJsonSubmitCommandRequest(request), options);
@@ -32,7 +32,7 @@ function mapJsonCommand(command) {
32
32
  },
33
33
  };
34
34
  }
35
- if (command instanceof ExerciseCommand) {
35
+ else if (command instanceof ExerciseCommand) {
36
36
  return {
37
37
  ExerciseCommand: {
38
38
  templateId: command.templateId,
@@ -42,7 +42,7 @@ function mapJsonCommand(command) {
42
42
  },
43
43
  };
44
44
  }
45
- if (command instanceof ExerciseByKeyCommand) {
45
+ else if (command instanceof ExerciseByKeyCommand) {
46
46
  return {
47
47
  ExerciseByKeyCommand: {
48
48
  templateId: command.templateId,
@@ -52,7 +52,7 @@ function mapJsonCommand(command) {
52
52
  },
53
53
  };
54
54
  }
55
- if (command instanceof CreateAndExerciseCommand) {
55
+ else if (command instanceof CreateAndExerciseCommand) {
56
56
  return {
57
57
  CreateAndExerciseCommand: {
58
58
  templateId: command.templateId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distrohelena/canton-typescript-sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",