Skip to main content

canton_token/
lib.rs

1//! Canton Network token-standard workflows (CIP-56 and CIP-0112).
2//!
3//! The token-standard **types** are generated from the Splice DARs and live in
4//! the `canton-splice-api-token-*` crates. This crate is the *workflow* over
5//! them: resolving a factory, asking a registry for a choice context,
6//! attaching the contracts it says to disclose, and exercising the choice.
7//!
8//! Nothing here re-declares a Daml type. That would duplicate the code
9//! generator and go stale on the next Splice release; the `Holding` this crate
10//! names is the same Rust type an application reads out of the ledger.
11//!
12//! # Why a registry is involved at all
13//!
14//! A transfer is exercised through an interface, and only the registry knows
15//! what reference data that choice needs — its own configuration contracts,
16//! the rules for an instrument, the current round. So the client asks for a
17//! choice context and gets back both the data to pass in and the contracts the
18//! participant must be shown. Those contracts are usually invisible to the
19//! submitting party, which is exactly what explicit disclosure is for.
20//!
21//! The registry's API is off-ledger HTTP, specified by the token standard's
22//! OpenAPI documents.
23
24#![forbid(unsafe_code)]
25
26pub mod allocation;
27mod context;
28pub mod holdings;
29mod registry;
30pub mod transfer;
31pub mod v2;
32
33pub use context::{ChoiceContext, ChoiceContextRequest, WireChoiceContext, WireDisclosedContract};
34pub use registry::{
35    AllocationChoice, AllocationInstructionChoice, FactoryWithContext, Instrument, RegistryClient,
36    RegistryInfo, TransferInstructionChoice, TransferKind,
37};
38/// The V1 (CIP-56) workflow, re-exported at the root because it is the one most
39/// networks run today. The V2 (CIP-0112) workflow keeps the same names and so
40/// stays behind [`v2`] — `token::transfer` and `token::v2::transfer` are
41/// different standards, and the path is what says which you meant.
42pub use transfer::{TokenCommand, accept, reject, transfer, withdraw};
43
44pub mod types {
45    //! The generated token-standard types this crate's API is written in terms
46    //! of, re-exported so they can be named without depending on each
47    //! generated crate directly.
48    //!
49    //! This is not a convenience. `transfer` takes a
50    //! [`Transfer`](v1::transfer_instruction::Transfer) and `v2::transfer`
51    //! takes a [`Transfer`](v2::transfer_instruction::Transfer) — so without
52    //! these a `cargo add canton` user could reach the *functions* through the
53    //! facade and be unable to name their arguments. The whole token
54    //! deliverable was unreachable that way, which is the same defect the
55    //! crate's own conformance suite states the rule against: a capability
56    //! that works only via a member crate is not one `cargo add canton`
57    //! delivers.
58    //!
59    //! Whole modules rather than a hand-listed set of types, because a list
60    //! goes stale the first time the standard adds a record and nothing
61    //! notices.
62
63    /// Metadata — `ExtraArgs`, `ChoiceContext`, `Metadata`. Shared by both
64    /// standards: there is no `metadata-v2`.
65    pub use canton_splice_api_token_metadata_v1::splice_api_token_metadata_v1::Splice_Api_Token_MetadataV1 as metadata;
66
67    /// CIP-56 — the V1 token standard.
68    pub mod v1 {
69        pub use canton_splice_api_token_allocation_instruction_v1::splice_api_token_allocation_instruction_v1::Splice_Api_Token_AllocationInstructionV1 as allocation_instruction;
70        pub use canton_splice_api_token_allocation_v1::splice_api_token_allocation_v1::Splice_Api_Token_AllocationV1 as allocation;
71        pub use canton_splice_api_token_holding_v1::splice_api_token_holding_v1::Splice_Api_Token_HoldingV1 as holding;
72        pub use canton_splice_api_token_transfer_instruction_v1::splice_api_token_transfer_instruction_v1::Splice_Api_Token_TransferInstructionV1 as transfer_instruction;
73    }
74
75    /// CIP-0112 — the V2 token standard.
76    pub mod v2 {
77        pub use canton_splice_api_token_allocation_instruction_v2::splice_api_token_allocation_instruction_v2::Splice_Api_Token_AllocationInstructionV2 as allocation_instruction;
78        pub use canton_splice_api_token_allocation_v2::splice_api_token_allocation_v2::Splice_Api_Token_AllocationV2 as allocation;
79        pub use canton_splice_api_token_holding_v2::splice_api_token_holding_v2::Splice_Api_Token_HoldingV2 as holding;
80        pub use canton_splice_api_token_transfer_events_v2::splice_api_token_transfer_events_v2::Splice_Api_Token_TransferEventsV2 as transfer_events;
81        pub use canton_splice_api_token_transfer_instruction_v2::splice_api_token_transfer_instruction_v2::Splice_Api_Token_TransferInstructionV2 as transfer_instruction;
82    }
83}
84
85/// The V1 `Holding` interface, at the root because it is the type a caller
86/// reaches for first. Everything else is under [`types`].
87pub use canton_splice_api_token_holding_v1::splice_api_token_holding_v1::Splice_Api_Token_HoldingV1::Holding;