chainhook_types/
contract_interface.rs

1// NOTE: This module is a very slightly simplified version of the
2// `clarity-vm` repository's [ContractInterface](https://github.com/stacks-network/stacks-blockchain/blob/eca1cfe81f0c0989ebd3e53c32e3e5d70ed83757/clarity/src/vm/analysis/contract_interface_builder/mod.rs#L368) type.
3// We've copied it here rather than using `clarity-vm` as a dependency to avoid circular dependencies.
4
5use std::{fmt, str::FromStr};
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub struct ContractInterface {
9    pub functions: Vec<ContractInterfaceFunction>,
10    pub variables: Vec<ContractInterfaceVariable>,
11    pub maps: Vec<ContractInterfaceMap>,
12    pub fungible_tokens: Vec<ContractInterfaceFungibleTokens>,
13    pub non_fungible_tokens: Vec<ContractInterfaceNonFungibleTokens>,
14    pub epoch: String,
15    pub clarity_version: String,
16}
17
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
19pub struct ContractInterfaceFunction {
20    pub name: String,
21    pub access: ContractInterfaceFunctionAccess,
22    pub args: Vec<ContractInterfaceFunctionArg>,
23    pub outputs: ContractInterfaceFunctionOutput,
24}
25#[allow(non_camel_case_types)]
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27pub enum ContractInterfaceFunctionAccess {
28    private,
29    public,
30    read_only,
31}
32#[allow(non_camel_case_types)]
33#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
34pub enum ContractInterfaceVariableAccess {
35    constant,
36    variable,
37}
38#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
39pub struct ContractInterfaceFunctionArg {
40    pub name: String,
41    #[serde(rename = "type")]
42    pub type_f: ContractInterfaceAtomType,
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
46pub struct ContractInterfaceFunctionOutput {
47    #[serde(rename = "type")]
48    pub type_f: ContractInterfaceAtomType,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52pub struct ContractInterfaceVariable {
53    pub name: String,
54    #[serde(rename = "type")]
55    pub type_f: ContractInterfaceAtomType,
56    pub access: ContractInterfaceVariableAccess,
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
60pub struct ContractInterfaceMap {
61    pub name: String,
62    pub key: ContractInterfaceAtomType,
63    pub value: ContractInterfaceAtomType,
64}
65
66#[allow(non_camel_case_types)]
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub enum ContractInterfaceAtomType {
69    none,
70    int128,
71    uint128,
72    bool,
73    principal,
74    buffer {
75        length: u32,
76    },
77    #[serde(rename = "string-utf8")]
78    string_utf8 {
79        length: u32,
80    },
81    #[serde(rename = "string-ascii")]
82    string_ascii {
83        length: u32,
84    },
85    tuple(Vec<ContractInterfaceTupleEntryType>),
86    optional(Box<ContractInterfaceAtomType>),
87    response {
88        ok: Box<ContractInterfaceAtomType>,
89        error: Box<ContractInterfaceAtomType>,
90    },
91    list {
92        #[serde(rename = "type")]
93        type_f: Box<ContractInterfaceAtomType>,
94        length: u32,
95    },
96    trait_reference,
97}
98
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
100pub struct ContractInterfaceTupleEntryType {
101    pub name: String,
102    #[serde(rename = "type")]
103    pub type_f: ContractInterfaceAtomType,
104}
105
106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
107pub struct ContractInterfaceFungibleTokens {
108    pub name: String,
109}
110
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112pub struct ContractInterfaceNonFungibleTokens {
113    pub name: String,
114    #[serde(rename = "type")]
115    pub type_f: ContractInterfaceAtomType,
116}
117#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, PartialOrd)]
118pub enum ClarityVersion {
119    Clarity1,
120    Clarity2,
121}
122
123impl fmt::Display for ClarityVersion {
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        match self {
126            ClarityVersion::Clarity1 => write!(f, "Clarity 1"),
127            ClarityVersion::Clarity2 => write!(f, "Clarity 2"),
128        }
129    }
130}
131
132impl FromStr for ClarityVersion {
133    type Err = String;
134    fn from_str(version: &str) -> Result<ClarityVersion, String> {
135        let s = version.to_string().to_lowercase();
136        if s == "clarity1" {
137            Ok(ClarityVersion::Clarity1)
138        } else if s == "clarity2" {
139            Ok(ClarityVersion::Clarity2)
140        } else {
141            Err(format!(
142                "Invalid clarity version. Valid versions are: Clarity1, Clarity2."
143            ))
144        }
145    }
146}
147#[repr(u32)]
148#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Copy, Serialize, Deserialize)]
149pub enum StacksEpochId {
150    Epoch10 = 0x01000,
151    Epoch20 = 0x02000,
152    Epoch2_05 = 0x02005,
153    Epoch21 = 0x0200a,
154    Epoch22 = 0x0200f,
155    Epoch23 = 0x02014,
156    Epoch24 = 0x02019,
157}
158
159impl std::fmt::Display for StacksEpochId {
160    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161        match self {
162            StacksEpochId::Epoch10 => write!(f, "1.0"),
163            StacksEpochId::Epoch20 => write!(f, "2.0"),
164            StacksEpochId::Epoch2_05 => write!(f, "2.05"),
165            StacksEpochId::Epoch21 => write!(f, "2.1"),
166            StacksEpochId::Epoch22 => write!(f, "2.2"),
167            StacksEpochId::Epoch23 => write!(f, "2.3"),
168            StacksEpochId::Epoch24 => write!(f, "2.4"),
169        }
170    }
171}