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    /// Struct type definitions.
42    pub structs: Vec<Struct>,
43    /// Record type definitions.
44    pub records: Vec<Record>,
45    /// On-chain key-value storage definitions.
46    pub mappings: Vec<Mapping>,
47    /// Storage variable definitions.
48    pub storage_variables: Vec<StorageVariable>,
49    /// Public entry points (program functions only, not internal helpers).
50    /// Compiled to Aleo `transition`s.
51    pub functions: Vec<Function>,
52}
53
54/// A struct type definition.
55#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
56pub struct Struct {
57    /// Path to the struct (e.g., `["Point"]` or `["utils", "Vector3"]` for module structs).
58    pub path: Path,
59    pub fields: Vec<StructField>,
60}
61
62/// A record type definition. Records have an implicit `owner: address` field.
63#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
64pub struct Record {
65    /// Path to the record (e.g., `["Token"]` or `["utils", "Token"]` for module records).
66    pub path: Path,
67    pub fields: Vec<RecordField>,
68}
69
70/// An on-chain key-value mapping.
71#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
72pub struct Mapping {
73    pub name: String,
74    pub key: Plaintext,
75    pub value: Plaintext,
76}
77
78/// A storage variable declaration.
79///
80/// # Lowering
81///
82/// Storage variables are lowered to mappings in Aleo bytecode:
83/// - `storage x: T` becomes `mapping x__: bool => T` (value stored at key `false`)
84#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
85pub struct StorageVariable {
86    pub name: String,
87    pub ty: StorageType,
88}
89
90/// Type for storage variables. Supports Vector unlike Plaintext.
91///
92/// # Lowering
93///
94/// Storage vectors are lowered to two mappings:
95/// - `storage vec: Vector<T>` becomes:
96///   - `mapping vec__: u32 => T` (elements by index)
97///   - `mapping vec__len__: bool => u32` (length at key `false`)
98#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
99pub enum StorageType {
100    Plaintext(Plaintext),
101    Vector(Box<StorageType>),
102}
103
104/// A public entry point (`fn` inside `program {}`). Compiled to an Aleo `transition`.
105#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
106pub struct Function {
107    pub name: String,
108    /// Whether this function has a finalize block. Compiled to an Aleo `finalize` scope.
109    pub is_final: bool,
110    pub inputs: Vec<Input>,
111    pub outputs: Vec<Output>,
112}
113
114/// A struct field.
115#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
116pub struct StructField {
117    pub name: String,
118    pub ty: Plaintext,
119}
120
121/// A record field with visibility mode.
122#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
123pub struct RecordField {
124    pub name: String,
125    pub ty: Plaintext,
126    pub mode: Mode,
127}
128
129/// A function input.
130#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
131pub struct Input {
132    pub name: String,
133    pub ty: FunctionInput,
134    pub mode: Mode,
135}
136
137/// A function output.
138#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
139pub struct Output {
140    pub ty: FunctionOutput,
141    pub mode: Mode,
142}
143
144/// Visibility mode for inputs, outputs, and record fields.
145#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
146pub enum Mode {
147    None,
148    Constant,
149    Private,
150    Public,
151}
152
153/// A fixed-length array type.
154#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
155pub struct Array {
156    pub element: Box<Plaintext>,
157    pub length: u32,
158}
159
160/// A reference to a struct type, possibly from another program.
161#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
162pub struct StructRef {
163    /// Path segments to the struct (e.g., `["utils", "Vector3"]` for `utils::Vector3`).
164    pub path: Path,
165    /// The program containing this struct, if external.
166    pub program: Option<String>,
167}
168
169/// A reference to a record type, possibly from another program.
170#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
171pub struct RecordRef {
172    /// Path segments to the record (e.g., `["Token"]` for a top-level record).
173    pub path: Path,
174    /// The program containing this record, if external.
175    pub program: Option<String>,
176}
177
178/// An optional type (`T?`).
179///
180/// # Lowering
181///
182/// In the compiled Aleo bytecode, `T?` is lowered to a struct:
183/// ```text
184/// struct "T?" { is_some: bool, val: T }
185/// ```
186#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
187pub struct Optional(pub Box<Plaintext>);
188
189/// A plaintext type (not encrypted). Used for struct fields, mapping keys/values, etc.
190#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
191pub enum Plaintext {
192    Primitive(Primitive),
193    Array(Array),
194    Struct(StructRef),
195    Optional(Optional),
196}
197
198/// Valid types for function inputs. Aleo: `transition` inputs.
199#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
200pub enum FunctionInput {
201    Plaintext(Plaintext),
202    Record(RecordRef),
203    DynamicRecord,
204}
205
206/// Valid types for function outputs. Aleo: `transition` outputs.
207#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
208pub enum FunctionOutput {
209    Plaintext(Plaintext),
210    Record(RecordRef),
211    /// Aleo `future` - the handle for an on-chain finalization.
212    Final,
213    DynamicRecord,
214}
215
216/// Primitive types that map directly to Aleo literal types.
217#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
218pub enum Primitive {
219    Address,
220    Boolean,
221    Field,
222    Group,
223    Identifier,
224    Scalar,
225    Signature,
226    Int(Int),
227    UInt(UInt),
228}
229
230/// Signed integer types.
231#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
232pub enum Int {
233    I8,
234    I16,
235    I32,
236    I64,
237    I128,
238}
239
240/// Unsigned integer types.
241#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
242pub enum UInt {
243    U8,
244    U16,
245    U32,
246    U64,
247    U128,
248}