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    /// Read-only `view fn` entry points (V15). Compiled to Aleo `view` blocks.
53    /// Off-consensus, plaintext-only inputs and outputs, no transactions or fees.
54    /// Defaults to empty for backwards compatibility with pre-V15 ABI consumers.
55    #[serde(default, skip_serializing_if = "Vec::is_empty")]
56    pub views: Vec<Function>,
57}
58
59/// The ABI for a single Leo interface.
60#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
61pub struct Interface {
62    /// Simple name (last path segment), e.g. "IToken".
63    pub name: String,
64    /// The program or library that owns this interface. Either a program id
65    /// like "foo.aleo" or a bare library name like "my_lib".
66    pub program: String,
67    /// Path to the interface within `program`, e.g. `["IToken"]` or `["mod", "IToken"]`.
68    pub path: Path,
69    /// Inherited interfaces, by reference. Not flattened.
70    pub parents: Vec<InterfaceRef>,
71    /// Locally declared function prototypes (`fn`).
72    pub functions: Vec<Function>,
73    /// Locally declared view-function prototypes (`view fn`).
74    #[serde(default, skip_serializing_if = "Vec::is_empty")]
75    pub views: Vec<Function>,
76    /// Locally declared record prototypes.
77    pub records: Vec<Record>,
78    /// Locally declared mapping prototypes.
79    pub mappings: Vec<Mapping>,
80    /// Locally declared storage variable prototypes.
81    pub storage_variables: Vec<StorageVariable>,
82    /// Struct definitions transitively referenced by the above. Only includes
83    /// types defined in `program`; external refs remain as `StructRef`.
84    pub structs: Vec<Struct>,
85}
86
87/// A reference to an interface, possibly from another program/library.
88#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
89pub struct InterfaceRef {
90    /// `None` means local to the current program/library.
91    pub program: Option<String>,
92    /// Path segments to the interface, e.g. `["IToken"]` or `["mod", "IToken"]`.
93    pub path: Path,
94}
95
96/// A struct type definition.
97#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
98pub struct Struct {
99    /// Path to the struct (e.g., `["Point"]` or `["utils", "Vector3"]` for module structs).
100    pub path: Path,
101    pub fields: Vec<StructField>,
102}
103
104/// A record type definition. Records have an implicit `owner: address` field.
105#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
106pub struct Record {
107    /// Path to the record (e.g., `["Token"]` or `["utils", "Token"]` for module records).
108    pub path: Path,
109    pub fields: Vec<RecordField>,
110}
111
112/// An on-chain key-value mapping.
113#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
114pub struct Mapping {
115    pub name: String,
116    pub key: Plaintext,
117    pub value: Plaintext,
118}
119
120/// A storage variable declaration.
121///
122/// # Lowering
123///
124/// Storage variables are lowered to mappings in Aleo bytecode:
125/// - `storage x: T` becomes `mapping x__: bool => T` (value stored at key `false`)
126#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
127pub struct StorageVariable {
128    pub name: String,
129    pub ty: StorageType,
130}
131
132/// Type for storage variables. Supports Vector unlike Plaintext.
133///
134/// # Lowering
135///
136/// Storage vectors are lowered to two mappings:
137/// - `storage vec: Vector<T>` becomes:
138///   - `mapping vec__: u32 => T` (elements by index)
139///   - `mapping vec__len__: bool => u32` (length at key `false`)
140#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
141pub enum StorageType {
142    Plaintext(Plaintext),
143    Vector(Box<StorageType>),
144}
145
146/// A public entry point (`fn` inside `program {}`). Compiled to an Aleo `transition`.
147#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
148pub struct Function {
149    pub name: String,
150    pub inputs: Vec<FunctionInput>,
151    pub outputs: Vec<FunctionOutput>,
152}
153
154/// A struct field.
155#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
156pub struct StructField {
157    pub name: String,
158    pub ty: Plaintext,
159}
160
161/// A record field with visibility mode.
162#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
163pub struct RecordField {
164    pub name: String,
165    pub ty: Plaintext,
166    pub mode: Mode,
167}
168
169/// Visibility mode for plaintext inputs/outputs and record fields.
170///
171/// Only plaintext I/O carries a visibility in Aleo (`.constant`/`.public`/`.private`); records,
172/// futures, and dynamic records have no such mode. The ABI always records a concrete visibility:
173/// unmoded source-level items are resolved during ABI generation the same way code generation
174/// lowers them — transition plaintext I/O and record fields become [`Mode::Private`], while view
175/// plaintext I/O becomes [`Mode::Public`].
176#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
177pub enum Mode {
178    Constant,
179    Private,
180    Public,
181}
182
183/// A fixed-length array type.
184#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
185pub struct Array {
186    pub element: Box<Plaintext>,
187    pub length: u32,
188}
189
190/// A reference to a struct type, possibly from another program.
191#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
192pub struct StructRef {
193    /// Path segments to the struct (e.g., `["utils", "Vector3"]` for `utils::Vector3`).
194    pub path: Path,
195    /// The program containing this struct, if external.
196    pub program: Option<String>,
197}
198
199/// A reference to a record type, possibly from another program.
200#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
201pub struct RecordRef {
202    /// Path segments to the record (e.g., `["Token"]` for a top-level record).
203    pub path: Path,
204    /// The program containing this record, if external.
205    pub program: Option<String>,
206}
207
208/// An optional type (`T?`).
209///
210/// # Lowering
211///
212/// In the compiled Aleo bytecode, `T?` is lowered to a struct:
213/// ```text
214/// struct "T?" { is_some: bool, val: T }
215/// ```
216#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
217pub struct Optional(pub Box<Plaintext>);
218
219/// A plaintext type (not encrypted). Used for struct fields, mapping keys/values, etc.
220#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
221pub enum Plaintext {
222    Primitive(Primitive),
223    Array(Array),
224    Struct(StructRef),
225    Optional(Optional),
226}
227
228/// Valid types for function inputs. Aleo: `transition` inputs. Only the plaintext variant carries
229/// a visibility [`Mode`]; records and dynamic records use the Aleo `.record` marker and have none.
230#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
231pub enum FunctionInput {
232    Plaintext { ty: Plaintext, mode: Mode },
233    Record(RecordRef),
234    DynamicRecord,
235}
236
237/// Valid types for function outputs. Aleo: `transition` outputs. Only the plaintext variant carries
238/// a visibility [`Mode`]; records, futures, and dynamic records have none.
239#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
240pub enum FunctionOutput {
241    Plaintext {
242        ty: Plaintext,
243        mode: Mode,
244    },
245    Record(RecordRef),
246    /// Aleo `future` - the handle for an on-chain finalization. Has no visibility.
247    Final,
248    DynamicRecord,
249}
250
251/// Primitive types that map directly to Aleo literal types.
252#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
253pub enum Primitive {
254    Address,
255    Boolean,
256    Field,
257    Group,
258    Identifier,
259    Scalar,
260    Signature,
261    Int(Int),
262    UInt(UInt),
263}
264
265/// Signed integer types.
266#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
267pub enum Int {
268    I8,
269    I16,
270    I32,
271    I64,
272    I128,
273}
274
275/// Unsigned integer types.
276#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
277pub enum UInt {
278    U8,
279    U16,
280    U32,
281    U64,
282    U128,
283}