Canton Console

Canton offers a console (REPL) where entities can be dynamically started and stopped, and a variety of administrative or debugging commands can be run.

All console commands must be valid Scala (the console is built on Ammonite - a Scala based scripting and REPL framework).

The examples/ sub-directories contain some sample scripts, with the extension .canton.

Node References

To issue the command a particular node, you must refer to it via its reference, which is a Scala variable. Named variables are created for all domain entities and participants using their configured identifiers. For example the sample examples/01-simple-topology/simple-topology.conf configuration file references the domain mydomain, and participants participant1 and participant2. These are available in the console as mydomain, participant and participant2. Additionally, the console provides the following generic references.

all
All Participants and Domains
all_domains
All Configured Domains
all_participants
All Configured Participants

Lifecycle Operations

These are supported by individual and sequences of domains and participants. If called on a sequence, operations will be called sequentially in the order of the sequence. For example:

all start

can be used to start all configured domains and participants.

start
Start the instance
stop
Stop the instance

Party Management

as_party_id

Convert string to PartyId object

Arguments:

  • uid: String

Return type

com.digitalasset.canton.identity.PartyId
disable_party

Disable party on participant

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • name: String
enable_party

Enable/add party to participant

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • name: String

Return type

com.digitalasset.canton.identity.PartyId
party_of

Return the admin party of a participant (e.g., in order to ping the participant)

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference

Return type

String

Ledger API Access

create

Build create command

Arguments:

  • packageId: String
  • module: String
  • template: String
  • arguments: Map[String,Any]

Return type

com.digitalasset.ledger.api.v1.commands.Command
exercise

Build exercise command from CreatedEvent

Arguments:

  • choice: String
  • arguments: Map[String,Any]
  • event: com.digitalasset.ledger.api.v1.event.CreatedEvent

Return type

com.digitalasset.ledger.api.v1.commands.Command
exercise

Build exercise command

Arguments:

  • packageId: String
  • module: String
  • template: String
  • choice: String
  • arguments: Map[String,Any]
  • contractId: String

Return type

com.digitalasset.ledger.api.v1.commands.Command

Other Top-level Commands

The following commands are available for convenience:

init_participant

Initializes participant

Arguments:

  • name: String
  • participant: com.digitalasset.canton.console.ParticipantReference
  • identityManager: com.digitalasset.canton.console.commands.IdentityAdministration
connect

Macro to connect a participant to a domain given by connection

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • domainAlias: String
  • connection: String
  • autoConnect: Boolean
  • essentialState: Option[com.digitalasset.canton.identity.v0.EssentialState]
  • certificatesPath: String
  • priority: Int
connect

Macro to connect a participant to a domain given by reference

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • domain: com.digitalasset.canton.console.DomainReference
participant_is_active

Test whether a participant is permissioned on a domain

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • domainAlias: String

Return type

Boolean
participant_is_active

Test whether a participant is permissioned on a domain

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • domain: com.digitalasset.canton.console.DomainReference

Return type

Boolean
status

Aggregate status info of all participants and domains

Return type

com.digitalasset.canton.console.ConsoleMacros.CantonStatus
find_packages_with_module

Find package with given module

Arguments:

  • participant: com.digitalasset.canton.console.ParticipantReference
  • module: String

Return type

Seq[String]
object_args

Reflective inspection of object arguments, handy to inspect case class objects

Arguments:

  • obj: T

Return type

List[String]

Return the list field names of the given object. Helpful function when inspecting the return result.

prettyContract

Extract most important information from a SerializableContract

Arguments:

  • contract: com.digitalasset.canton.transaction.SerializableContract

Return type

(String, String, String, List[(String, String)])

Utility function to extract data from ``SerializableContract`` into a smaller and more accessible form for inspection. You can use it along the lines of ``pcs_search.map(_._2).map(prettyContract)`` to reduce the complexity of the ``SerializableContract`` data structure.

type_args

Reflective inspection of type arguments, handy to inspect case class types

Return type

List[String]

Return the list of field names of the given type. Helpful function when creating new objects for requests.

Participant Administration Commands

Packages

accept_dar

Accept the offer to share a DAR

Arguments:

  • shareId: String
dar_sharing_whitelist_add

Add party to my DAR sharing whitelist

Arguments:

  • partyId: String
dar_sharing_whitelist_list
List parties that are currently whitelisted to share DARs with me
dar_sharing_whitelist_remove

Remove party from my DAR sharing whitelist

Arguments:

  • partyId: String
download_dar

Downloads the DAR file with the given hash to the given directory

Arguments:

  • darHash: String
  • directory: String
list_dar_sharing_offers

List received DAR sharing offers

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.ListShareOffersResponse.Item]
list_dar_sharing_requests

List pending requests to share a DAR with others

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.ListShareRequestsResponse.Item]
list_dars

List installed DAR files

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.DarDescription]
list_package_contents

List package contents

Arguments:

  • packageId: String

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.ModuleDescription]
list_packages

List installed packages

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.PackageState]
reject_dar

Reject the offer to share a DAR

Arguments:

  • shareId: String
  • reason: String
share_dar

Share DAR with other participants

Arguments:

  • darHash: String
  • participantParty: String
upload_dar

Upload a DAR

Arguments:

  • path: String

Return type

String
upload_package

Upload a raw daml-lf package

Arguments:

  • path: String

Domain Connectivity

accept_agreement

Accept the service agreement of the given domain alias

Arguments:

  • domainAlias: String
  • agreementId: String
connect_domain

Connect this participant to the given domain

Arguments:

  • domainAlias: String
disconnect_domain

Disconnect this participant from the given domain

Arguments:

  • domainAlias: String
get_agreement

Get the service agreement of the given domain alias and if it has been accepted already.

Arguments:

  • domainAlias: String

Return type

Option[(com.digitalasset.canton.participant.admin.api.v0.Agreement, Boolean)]
list_configured_domains

List the configured domains of this participant

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.ListConfiguredDomainsResponse.Result]
list_connected_domains

List the connected domains of this participant

Return type

Seq[com.digitalasset.canton.participant.admin.api.v0.ListConnectedDomainsResponse.Result]
modify_domain_connection

Modify existing domain connection

Arguments:

  • alias: String
  • connection: String
  • autoConnect: Boolean
  • essentialState: Option[com.digitalasset.canton.identity.v0.EssentialState]
  • certificatesPath: String
  • priority: Int
register_domain

Register new domain connection

Arguments:

  • alias: String
  • connection: String
  • autoConnect: Boolean
  • essentialState: Option[com.digitalasset.canton.identity.v0.EssentialState]
  • certificatesPath: String
  • priority: Int
status

Get human readable status info

Return type

com.digitalasset.canton.participant.admin.api.v0.StatusResponse

Diagnostics

bong

Send a bong to a set of target parties over the ledger. Levels > 0 leads to an exploding ping with exponential number of contracts.

Arguments:

  • targets: Set[String]
  • timeoutMillis: Long
  • levels: Long
  • gracePeriodMillis: Long
  • workflowId: String

Return type

Option[scala.concurrent.duration.Duration]

initiate a racy ping to multiple participants, measuring the roundtrip time of the fasted responder, with an optional timeout. Grace-period is the time the bong will wait for a duplicate spent (which would indicate an error in the system) before exiting. If levels > 0, the ping command will lead to a binary explosion and subsequent dilation of contracts, where ``level`` determines the number of levels we will explode. As a result, the system will create (2^(L+2) - 3) contracts (where L stands for ``level``). The bong command comes handy to run a burst test against the system, leading quickly to an overloading state.

ping

Send a ping to the target party over the ledger. Times out after the given number of milliseconds (default 10000)

Arguments:

  • target: String
  • timeoutMillis: Long
  • workflowId: String

Return type

Option[scala.concurrent.duration.Duration]

Inspection

acs_search

Lookup of active contracts

Arguments:

  • domainAlias: String
  • filterId: String
  • filterPackage: String
  • filterTemplate: String
  • limit: Int

Return type

List[com.digitalasset.canton.transaction.SerializableContract]
event_search

Lookup of events

Arguments:

  • domain: String

Return type

Seq[(String, com.digitalasset.canton.participant.sync.TimestampedEvent)]

Show the event logs. To select only events from a particular domain, use the domain alias. Leave the domain blank to search the combined event log.

pcs_search

Lookup contracts in the Private Contract Store

Arguments:

  • domainAlias: String
  • filterId: String
  • filterPackage: String
  • filterTemplate: String
  • activeSet: Boolean
  • limit: Int

Return type

List[(Boolean, com.digitalasset.canton.transaction.SerializableContract)]

Get raw access to the PCS of the given domain sync controller. The filter commands will check if the target value ``contains`` the given string. The arguments can be started with ``^`` such that ``startsWith`` is used for comparision or ``!`` to use ``equals``. The ``activeSet`` argument allows to restrict the search to the active contract set.

recent_heartbeat

Get a recent heartbeat

Arguments:

  • domain: com.digitalasset.canton.DomainAlias

Return type

Option[com.digitalasset.canton.sequencing.Heartbeat]
sequencer_messages

Retrieve all sequencer messages

Arguments:

  • domain: String

Return type

Option[Iterable[com.digitalasset.canton.sequencing.SignedDeliverEvent[com.digitalasset.canton.transaction.protocol.ProtocolMessageContent]]]
transaction_search

Lookup of transactions

Arguments:

  • domain: String

Return type

Seq[com.digitalasset.canton.participant.store.StoredTransaction]
transfer_search

Lookup of transfers

Arguments:

  • targetDomainAlias: String
  • originDomainAlias: Option[String]
  • timestamp: Option[com.digitalasset.canton.Timestamp]
  • limit: Int

Return type

Seq[com.digitalasset.canton.participant.transaction.transfer.TransferData]
object_args

Reflective inspection of object arguments, handy to inspect case class objects

Arguments:

  • obj: T

Return type

List[String]

Return the list field names of the given object. Helpful function when inspecting the return result.

prettyContract

Extract most important information from a SerializableContract

Arguments:

  • contract: com.digitalasset.canton.transaction.SerializableContract

Return type

(String, String, String, List[(String, String)])

Utility function to extract data from ``SerializableContract`` into a smaller and more accessible form for inspection. You can use it along the lines of ``pcs_search.map(_._2).map(prettyContract)`` to reduce the complexity of the ``SerializableContract`` data structure.

type_args

Reflective inspection of type arguments, handy to inspect case class types

Return type

List[String]

Return the list of field names of the given type. Helpful function when creating new objects for requests.

Domain Administration Commands

export_essential_state

Export essential state to file

Arguments:

  • outputFile: String

The essential state represents the root of trust for a Canton domain (equivalent to a root certificate). You can read more in the Canton architecture documentation. Use this command to download the state to a file, such that it can be shipped to a participant via a secure channel.

get_essential_state

Download essential state

Return type

com.digitalasset.canton.identity.v0.EssentialState

The essential state represents the root of trust for a Canton domain (equivalent to a root certificate). You can read more in the Canton architecture documentation. Use this command to retrieve and inspect the state.

set_participant_state

Change state and trust level of participant

Arguments:

  • participant: String
  • state: com.digitalasset.canton.identity.v0.ParticipantPermission
  • trustLevel: com.digitalasset.canton.identity.v0.TrustLevel

Set the state of the participant within the domain. Valid states are 'Active', 'Confirming', 'Disabled'. Valid trust levels are 'Vip' and 'Ordinary'.

status

Get human readable status info

Return type

com.digitalasset.canton.domain.admin.api.v0.StatusResponse

Key Operations

Key operations are supported on all modules (domain, identity manager and participant node). They allow to inspect the private key vault and download the public keys. Also, foreign public keys which are used in identity management operations can be uploaded here. The purpose of such an import is to support the identity management commands that identify a key using the corresponding fingerprint instead of the serialized key.

export_public_key

Export public key

Arguments:

  • fingerprint: String
  • outputFile: String

Return type

String
generate_key

Generate new public/private key pair and store it in the vault

Arguments:

  • purposes: Set[com.digitalasset.canton.identity.v0.KeyPurpose]
  • context: String

Return type

com.digitalasset.canton.identity.admin.api.v0.KeyResult
import_public_key

Import public key from byte string

Arguments:

  • bytes: com.google.protobuf.ByteString
  • context: String

Return type

String

Upload a public key and store it together with a string used to provide some context to that key.

list_my_keys

List keys in private vault

Arguments:

  • filterFingerprint: String
  • filterContext: String
  • purpose: Set[com.digitalasset.canton.identity.v0.KeyPurpose]

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.KeyResult]

Returns all public keys to the corresponding private keys in the key vault. Optional arguments can be used for filtering.

list_public_keys

List public keys in registry

Arguments:

  • filterFingerprint: String
  • filterContext: String

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.KeyResult]

Returns all public keys that have been added to the key registry. Optional arguments can be used for filtering.

load_public_key

Load and import public key from file

Arguments:

  • filename: String
  • context: String

Return type

String

Identity Operations

Identity operations are supported on both, the participant and the domain. However, the identity commands have a different effect when run on the domain versus when run on the participant node. On the domain, the commands immediately affect the identity state of the domain, which means that all changes are immediately pushed to the connected participants. On the participant node, they affect the local identity manager state, while the local identity manager will try to publish the local state on the remote domains.

Identity Inspection Commands

The identity inspection merges all the identity information the given node has into a single view, including all connected domains for a participant. Use it to inspect the actual identity state used by the synchronization protocol.

The filterStore argument can be used to inspect the different identity stores. You can either pass in a domain-id in order to get the authoritative identity state of a particular domain. Or you can use Authorized to inspect the locally authorized store.

get_id

Return id of node (if initialized)

Return type

Option[String]
list_identifier_delegation

List identifier delegation transactions

Arguments:

  • filterStore: String
  • from: Option[java.time.Instant]
  • until: Option[java.time.Instant]
  • resultType: com.digitalasset.canton.identity.admin.api.v0.BaseQuery.ResultType

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListIdentifierDelegationResult.Result]
list_key_owners

List active owners with keys where for a given owner type.

Arguments:

  • filterOwner: String
  • filterOwnerType: com.digitalasset.canton.identity.v0.OwnerType
  • filterDomain: String
  • asOf: Option[java.time.Instant]

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListKeyOwnersResponse.Result]

Owner type can be 'Participant' (default), 'Mediator','Sequencer', 'DomainIdentityManager'. This command is quite powerful, as it allows deep inspection of the identity state. The response includes the public keys.

list_metadata_update

List metadata updates

Arguments:

  • filterStore: String
  • from: Option[java.time.Instant]
  • until: Option[java.time.Instant]
  • resultType: com.digitalasset.canton.identity.admin.api.v0.BaseQuery.ResultType
  • filterParty: String

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListMetadataUpdateResult.Result]
list_namespace_delegation

List namespace delegation transactions

Arguments:

  • filterStore: String
  • from: Option[java.time.Instant]
  • until: Option[java.time.Instant]
  • resultType: com.digitalasset.canton.identity.admin.api.v0.BaseQuery.ResultType

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListNamespaceDelegationResult.Result]
list_owner_to_key_mapping

List owner to key mapping transactions

Arguments:

  • filterStore: String
  • from: Option[java.time.Instant]
  • until: Option[java.time.Instant]
  • resultType: com.digitalasset.canton.identity.admin.api.v0.BaseQuery.ResultType
  • filterOwner: String
  • filterKeyPurpose: Option[com.digitalasset.canton.identity.v0.KeyPurpose]

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListOwnerToKeyMappingResult.Result]
list_parties

List active parties as permissioned on domains.

Arguments:

  • filterParty: String
  • filterDomain: String
  • asOf: Option[java.time.Instant]

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListPartiesResponse.Result]

This command allows to deeply inspect the identity state used for synchronisation. The response is built from the timestamped identity transactions of each domain.

list_party_to_participant

List party to participant mapping transactions

Arguments:

  • filterStore: String
  • from: Option[java.time.Instant]
  • until: Option[java.time.Instant]
  • resultType: com.digitalasset.canton.identity.admin.api.v0.BaseQuery.ResultType
  • filterParty: String
  • filterParticipant: String
  • filterRequestSide: Option[com.digitalasset.canton.identity.v0.RequestSide]
  • filterPermission: Option[com.digitalasset.canton.identity.v0.ParticipantPermission]

Return type

Seq[com.digitalasset.canton.identity.admin.api.v0.ListPartyToParticipantResult.Result]

Return a list of party to participant mappings matching the provided optional filter arguments.

list_stores

List available identity stores

Return type

Seq[String]

Identity Management Commands

The identity manager write service is the key service used to manipulate the identity state. In all commands, we can use fingerprints to refer to public keys. Internally, these fingerprints are resolved using the key registry (which is a map of Fingerprint -> PublicKey). Any key can be added to the key registry using the load / import commands.

All commands here share two arguments:

  • <operation> which can be Add / Remove.
  • <signedBy> which is the key used to authorize the identity transaction.

The used key needs to be present in the key-vault and needs to be eligible.

In order to use the operations conveniently, the corresponding case classes can be imported using

import com.digitalasset.canton.identity.v0.IdentityChangeOp._

and similar for all other enums used as function arguments.

authorize_identifier_delegation

Change identifier delegation

Arguments:

  • ops: com.digitalasset.canton.identity.v0.IdentityChangeOp
  • signedBy: String
  • identifier: String
  • authorizedKey: String

Return type

com.google.protobuf.ByteString

Delegates the authority of a certain identifier to a certain key. This corresponds to a normal certificate which binds identifier to a key. The keys are referred to using their fingerprints. They need to be either locally generated or have been previously imported. ops: Either Add or Remove the delegation. signedBy: Refers to the fingerprint of the authorizing key which in turn refers to a specific, locally existing certificate. authorizedKey: Fingerprint of the key to be authorized.

authorize_metadata_update

Change party metadata

Arguments:

  • ops: com.digitalasset.canton.identity.v0.IdentityChangeOp
  • signedBy: String
  • party: String
  • metadata: Option[com.digitalasset.canton.identity.v0.Metadata]
  • visibility: com.digitalasset.canton.identity.v0.MetadataUpdate.Visibility

Return type

com.google.protobuf.ByteString

This is currently a stub

authorize_namespace_delegation

Change namespace delegation

Arguments:

  • ops: com.digitalasset.canton.identity.v0.IdentityChangeOp
  • signedBy: String
  • namespace: String
  • authorizedKey: String

Return type

com.google.protobuf.ByteString

Delegates the authority to authorize identity transactions in a certain namespace to a certain key. The keys are referred to using their fingerprints. They need to be either locally generated or have been previously imported. ops: Either Add or Remove the delegation. signedBy: Refers to the fingerprint of the authorizing key. The authorizing key needs to be either the authorizedKey for root certificates. Otherwise, the signedBy key needs to refer to a previously authorized key, which means that we use the signedBy key to refer to a locally available CA. authorizedKey: Fingerprint of the key to be authorized. If signedBy equals authorizedKey, then this transaction corresponds to a self-signed root certificate. If the keys differ, then we get an intermediate CA.

authorize_owner_to_key_mapping

Change owner to key mapping

Arguments:

  • ops: com.digitalasset.canton.identity.v0.IdentityChangeOp
  • signedBy: String
  • ownerType: com.digitalasset.canton.identity.v0.OwnerType
  • owner: String
  • key: String
  • purposes: Set[com.digitalasset.canton.identity.v0.KeyPurpose]

Return type

com.google.protobuf.ByteString

Change a owner to key mapping. A key owner is anyone in the system that needs a key-pair known to all members (participants, mediator, sequencer, identity manager) of a domain. ops: Either Add or Remove the key mapping update. signedBy: Refers to the fingerprint of the authorizing key which in turn refers to a specific, locally existing certificate. ownerType: Role of the following owner (Participant, Sequencer, Mediator, DomainIdentityManager) owner: Unique identifier of the owner. key: Fingerprint of key purposes: The purposes of the owner to key mapping.

authorize_party_to_participant

Change party to participant mapping

Arguments:

  • ops: com.digitalasset.canton.identity.v0.IdentityChangeOp
  • signedBy: String
  • party: String
  • participant: String
  • side: com.digitalasset.canton.identity.v0.RequestSide
  • permission: com.digitalasset.canton.identity.v0.ParticipantPermission

Return type

com.google.protobuf.ByteString

Change the association of a party to a participant. If both identifiers are in the same namespace, then the request-side is Both. If they differ, then we need to say whether the request comes from the party (RequestSide.From) or from the participant (RequestSide.To). And, we need the matching request of the other side. ops: Either Add or Remove the mapping signedBy: Refers to the fingerprint of the authorizing key which in turn refers to a specific, locally existing certificate. party: The unique identifier of the party we want to map to a participant. participant: The unique identifier of the participant to which the party is supposed to be mapped. side: The request side (RequestSide.From if we the transaction is from the perspective of the party, RequestSide.To from the participant.) privilege: The privilege of the given participant which allows us to restrict an association (e.g. Confirmation or Observation).

init_id

Initialize the node with a unique identifier

Arguments:

  • identifier: String
  • fingerprint: String

Return type

String

DAML Scenario Execution

For testing purposes, Canton supports executing DAML scenarios directly, instead of executing Ledger API commands.

Note

This functionality is only there for testing purposes, and functions only when, for every party p in the scenario, the console was started in a configuration with a participant P such that: 1. P hosts a party whose human-readable part of the identifier is p (e.g., “Alice”) 2. P is started by the console, i.e., it is not running in daemon mode.

list

List DAML scenarios

Return type

Seq[String]
load

Load a DAR file into the scenario runner

Arguments:

  • path: String

Return type

Seq[com.digitalasset.daml.lf.data.Ref.PackageId]
run

Run a DAML scenario

Arguments:

  • scenario: String
  • defaultDomain: Option[com.digitalasset.canton.DomainAlias]
runAll

Run all DAML scenarios

Return type

String

FAQ

  • Why do you have an additional new line between each line in your example scripts?
    • When we write participant1 start the scala compiler translates this into participant1.start(). This works great in the console when each line is parsed independently. However with a script all of it’s content is parsed at once, and in which case if there is anything on the line following participant1 start it will assume it is an argument for start and fail. An additional newline prevents this. Adding parenthesis would also work.
  • How can I use nested import statements to split my script into multiple files?
    • Ammonite supports splitting scripts into several files using two mechanisms. The old one is interp.load.module(..). The new one is import $file.<fname>. The former will compile the module as a whole, which means that variables defined in one module can not be used in another one as they are not available during compilation. The import $file. syntax however will make all variables accessible in the importing script. However, it only works with relative paths as e.g. ../path/to/foo/bar.sc needs to be converted into import $file.^.path.to.foo.bar and it only works if the script file is named with suffix .sc.
  • Can I run the console against a remotely running participant or domain?
    • Yes, you can. Make sure that the admin-api ports are accessible from your machine and then just run the Canton process with the interactive console, using the same configuration settings for the admin-api. Just don’t start the nodes locally. This will work except the “deep inspection” commands which can only be run locally.