Skip to main content

canton_daml/
commands.rs

1//! Builders that turn typed templates and choices into Ledger API commands.
2//!
3//! These construct the `Command` values the client crate (`canton-ledger`)
4//! submits — they perform no I/O. A [`Template`] payload becomes a
5//! `CreateCommand`; a [`Choice`] argument exercised on a [`ContractId`] becomes
6//! an `ExerciseCommand`. Both use the template's upgrade-friendly
7//! [`Template::template_id`] (the `#<package-name>` form).
8
9use canton_proto::com::daml::ledger::api::v2 as pb;
10
11use crate::choice::Choice;
12use crate::primitives::ContractId;
13use crate::template::{Contract, Template, WithKey};
14use crate::value::ToValue;
15
16/// A `CreateCommand` for a new contract of template `T` from its payload.
17#[must_use]
18pub fn create_command<T: Template>(payload: &T) -> pb::Command {
19    wrap(pb::command::Command::Create(pb::CreateCommand {
20        template_id: Some(T::template_id()),
21        create_arguments: Some(payload.to_record()),
22    }))
23}
24
25/// An `ExerciseCommand` exercising choice `C` (with `argument`) on the contract
26/// `contract_id` of template or interface `T`.
27#[must_use]
28pub fn exercise_command<T, C>(contract_id: &ContractId<T>, argument: &C) -> pb::Command
29where
30    T: Contract,
31    C: Choice<T> + ToValue,
32{
33    wrap(pb::command::Command::Exercise(pb::ExerciseCommand {
34        template_id: Some(T::template_id()),
35        contract_id: contract_id.as_str().to_string(),
36        choice: C::NAME.to_string(),
37        choice_argument: Some(argument.to_value()),
38    }))
39}
40
41/// An `ExerciseByKeyCommand` exercising choice `C` (with `argument`) on the
42/// contract of template `T` identified by its contract `key`.
43#[must_use]
44pub fn exercise_by_key_command<T, C>(key: &T::Key, argument: &C) -> pb::Command
45where
46    T: WithKey,
47    C: Choice<T> + ToValue,
48{
49    wrap(pb::command::Command::ExerciseByKey(
50        pb::ExerciseByKeyCommand {
51            template_id: Some(T::template_id()),
52            contract_key: Some(key.to_value()),
53            choice: C::NAME.to_string(),
54            choice_argument: Some(argument.to_value()),
55        },
56    ))
57}
58
59/// Wrap a command variant in the top-level `Command` envelope.
60fn wrap(command: pb::command::Command) -> pb::Command {
61    pb::Command {
62        command: Some(command),
63    }
64}