Skip to main content

leo_abi_types/
lib.rs

1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17//! ABI type definitions for Leo programs.
18//!
19//! This crate provides types that describe the public interface of a Leo program,
20//! including functions, mappings, and all related types. The ABI enables downstream
21//! tooling to interact with deployed Leo programs.
22//!
23//! # Lowered Types
24//!
25//! Some Leo types have an alternative "lowered" form in the compiled Aleo bytecode.
26//! Downstream tooling should apply these transformations to understand the on-chain
27//! representation:
28//!
29//! - [`Optional`] - Lowered to a struct with `is_some: bool` and `val: T` fields.
30
31use serde::{Deserialize, Serialize};
32
33/// A path to a type (e.g., `["utils", "math", "Vector3"]` for `utils::math::Vector3`).
34pub type Path = Vec<String>;
35
36/// The complete ABI for a Leo program.
37#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
38pub struct Program {
39    /// The program identifier (e.g., "token.aleo").
40    pub program: String,
41    /// Interfaces this program implements, by reference.
42    pub implements: Vec<InterfaceRef>,
43    /// Struct type definitions.
44    pub structs: Vec<Struct>,
45    /// Record type definitions.
46    pub records: Vec<Record>,
47    /// On-chain key-value storage definitions.
48    pub mappings: Vec<Mapping>,
49    /// Storage variable definitions.
50    pub storage_variables: Vec<StorageVariable>,
51    /// Public entry points (program functions only, not internal helpers).
52    /// Compiled to Aleo `transition`s.
53    pub functions: Vec<Function>,
54    /// Read-only `view fn` entry points (V15). Compiled to Aleo `view` blocks.
55    /// Off-consensus, plaintext-only inputs and outputs, no transactions or fees.
56    /// Defaults to empty for backwards compatibility with pre-V15 ABI consumers.
57    #[serde(default, skip_serializing_if = "Vec::is_empty")]
58    pub views: Vec<Function>,
59}
60
61/// The ABI for a single Leo interface.
62#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
63pub struct Interface {
64    /// Simple name (last path segment), e.g. "IToken".
65    pub name: String,
66    /// The program or library that owns this interface. Either a program id
67    /// like "foo.aleo" or a bare library name like "my_lib".
68    pub program: String,
69    /// Path to the interface within `program`, e.g. `["IToken"]` or `["mod", "IToken"]`.
70    pub path: Path,
71    /// Inherited interfaces, by reference. Not flattened.
72    pub parents: Vec<InterfaceRef>,
73    /// Locally declared function prototypes (`fn`).
74    pub functions: Vec<Function>,
75    /// Locally declared view-function prototypes (`view fn`).
76    #[serde(default, skip_serializing_if = "Vec::is_empty")]
77    pub views: Vec<Function>,
78    /// Locally declared record prototypes.
79    pub records: Vec<Record>,
80    /// Locally declared mapping prototypes.
81    pub mappings: Vec<Mapping>,
82    /// Locally declared storage variable prototypes.
83    pub storage_variables: Vec<StorageVariable>,
84    /// Struct definitions transitively referenced by the above. Only includes
85    /// types defined in `program`; external refs remain as `StructRef`.
86    pub structs: Vec<Struct>,
87}
88
89/// A reference to an interface, possibly from another program/library.
90#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
91pub struct InterfaceRef {
92    /// `None` means local to the current program/library.
93    pub program: Option<String>,
94    /// Path segments to the interface, e.g. `["IToken"]` or `["mod", "IToken"]`.
95    pub path: Path,
96}
97
98/// A const generic parameter on an interface function prototype.
99#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
100pub struct ConstParameter {
101    pub name: String,
102    pub ty: Plaintext,
103}
104
105/// A struct type definition.
106#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
107pub struct Struct {
108    /// Path to the struct (e.g., `["Point"]` or `["utils", "Vector3"]` for module structs).
109    pub path: Path,
110    pub fields: Vec<StructField>,
111}
112
113/// A record type definition. Records have an implicit `owner: address` field.
114#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
115pub struct Record {
116    /// Path to the record (e.g., `["Token"]` or `["utils", "Token"]` for module records).
117    pub path: Path,
118    pub fields: Vec<RecordField>,
119}
120
121/// An on-chain key-value mapping.
122#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
123pub struct Mapping {
124    pub name: String,
125    pub key: Plaintext,
126    pub value: Plaintext,
127}
128
129/// A storage variable declaration.
130///
131/// # Lowering
132///
133/// Storage variables are lowered to mappings in Aleo bytecode:
134/// - `storage x: T` becomes `mapping x__: bool => T` (value stored at key `false`)
135#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
136pub struct StorageVariable {
137    pub name: String,
138    pub ty: StorageType,
139}
140
141/// Type for storage variables. Supports Vector unlike Plaintext.
142///
143/// # Lowering
144///
145/// Storage vectors are lowered to two mappings:
146/// - `storage vec: Vector<T>` becomes:
147///   - `mapping vec__: u32 => T` (elements by index)
148///   - `mapping vec__len__: bool => u32` (length at key `false`)
149#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
150pub enum StorageType {
151    Plaintext(Plaintext),
152    Vector(Box<StorageType>),
153}
154
155/// A public entry point (`fn` inside `program {}`). Compiled to an Aleo `transition`.
156#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
157pub struct Function {
158    pub name: String,
159    /// Whether this function has a finalize block. Compiled to an Aleo `finalize` scope.
160    pub is_final: bool,
161    /// Const generic parameters. Always empty for program ABIs (post-monomorphization);
162    /// may be populated for interface function prototypes.
163    pub const_parameters: Vec<ConstParameter>,
164    pub inputs: Vec<Input>,
165    pub outputs: Vec<Output>,
166}
167
168/// A struct field.
169#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
170pub struct StructField {
171    pub name: String,
172    pub ty: Plaintext,
173}
174
175/// A record field with visibility mode.
176#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
177pub struct RecordField {
178    pub name: String,
179    pub ty: Plaintext,
180    pub mode: Mode,
181}
182
183/// A function input.
184#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
185pub struct Input {
186    pub name: String,
187    pub ty: FunctionInput,
188    pub mode: Mode,
189}
190
191/// A function output.
192#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
193pub struct Output {
194    pub ty: FunctionOutput,
195    pub mode: Mode,
196}
197
198/// Visibility mode for inputs, outputs, and record fields.
199#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
200pub enum Mode {
201    None,
202    Constant,
203    Private,
204    Public,
205}
206
207/// A fixed-length array type.
208#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
209pub struct Array {
210    pub element: Box<Plaintext>,
211    pub length: u32,
212}
213
214/// A reference to a struct type, possibly from another program.
215#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
216pub struct StructRef {
217    /// Path segments to the struct (e.g., `["utils", "Vector3"]` for `utils::Vector3`).
218    pub path: Path,
219    /// The program containing this struct, if external.
220    pub program: Option<String>,
221}
222
223/// A reference to a record type, possibly from another program.
224#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
225pub struct RecordRef {
226    /// Path segments to the record (e.g., `["Token"]` for a top-level record).
227    pub path: Path,
228    /// The program containing this record, if external.
229    pub program: Option<String>,
230}
231
232/// An optional type (`T?`).
233///
234/// # Lowering
235///
236/// In the compiled Aleo bytecode, `T?` is lowered to a struct:
237/// ```text
238/// struct "T?" { is_some: bool, val: T }
239/// ```
240#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
241pub struct Optional(pub Box<Plaintext>);
242
243/// A plaintext type (not encrypted). Used for struct fields, mapping keys/values, etc.
244#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
245pub enum Plaintext {
246    Primitive(Primitive),
247    Array(Array),
248    Struct(StructRef),
249    Optional(Optional),
250}
251
252/// Valid types for function inputs. Aleo: `transition` inputs.
253#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
254pub enum FunctionInput {
255    Plaintext(Plaintext),
256    Record(RecordRef),
257    DynamicRecord,
258}
259
260/// Valid types for function outputs. Aleo: `transition` outputs.
261#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
262pub enum FunctionOutput {
263    Plaintext(Plaintext),
264    Record(RecordRef),
265    /// Aleo `future` - the handle for an on-chain finalization.
266    Final,
267    DynamicRecord,
268}
269
270/// Primitive types that map directly to Aleo literal types.
271#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
272pub enum Primitive {
273    Address,
274    Boolean,
275    Field,
276    Group,
277    Identifier,
278    Scalar,
279    Signature,
280    Int(Int),
281    UInt(UInt),
282}
283
284/// Signed integer types.
285#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
286pub enum Int {
287    I8,
288    I16,
289    I32,
290    I64,
291    I128,
292}
293
294/// Unsigned integer types.
295#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
296pub enum UInt {
297    U8,
298    U16,
299    U32,
300    U64,
301    U128,
302}