Skip to main content

neo_types/
manifest.rs

1// Copyright (c) 2025-2026 R3E Network
2// Licensed under the MIT License
3
4use std::string::String;
5use std::vec::Vec;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[cfg(feature = "serde")]
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12struct ManifestExtraMetadata {
13    #[serde(default)]
14    version: String,
15    #[serde(default)]
16    author: String,
17    #[serde(default)]
18    email: String,
19    #[serde(default)]
20    description: String,
21}
22
23#[cfg(feature = "serde")]
24fn default_version() -> String {
25    "1.0.0".to_string()
26}
27
28#[cfg(feature = "serde")]
29fn default_author() -> String {
30    "neo-devpack".to_string()
31}
32
33/// Neo N3 Contract Manifest
34#[derive(Debug, Clone, PartialEq, Eq)]
35#[cfg_attr(feature = "serde", derive(Serialize))]
36pub struct NeoContractManifest {
37    pub name: String,
38    #[cfg_attr(feature = "serde", serde(default = "default_version"))]
39    pub version: String,
40    #[cfg_attr(feature = "serde", serde(default = "default_author"))]
41    pub author: String,
42    #[cfg_attr(feature = "serde", serde(default))]
43    pub email: String,
44    #[cfg_attr(feature = "serde", serde(default))]
45    pub description: String,
46    pub abi: NeoContractABI,
47    pub permissions: Vec<NeoContractPermission>,
48    pub trusts: Vec<String>,
49    #[cfg_attr(feature = "serde", serde(alias = "supportedstandards", default))]
50    pub supported_standards: Vec<String>,
51}
52
53#[cfg(feature = "serde")]
54impl<'de> Deserialize<'de> for NeoContractManifest {
55    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
56    where
57        D: serde::Deserializer<'de>,
58    {
59        #[derive(Deserialize)]
60        struct RawManifest {
61            name: String,
62            #[serde(default = "default_version")]
63            version: String,
64            #[serde(default = "default_author")]
65            author: String,
66            #[serde(default)]
67            email: String,
68            #[serde(default)]
69            description: String,
70            abi: NeoContractABI,
71            permissions: Vec<NeoContractPermission>,
72            trusts: Vec<String>,
73            #[serde(alias = "supportedstandards", default)]
74            supported_standards: Vec<String>,
75            #[serde(default)]
76            extra: Option<ManifestExtraMetadata>,
77        }
78
79        let raw = RawManifest::deserialize(deserializer)?;
80        let mut version = raw.version;
81        let mut author = raw.author;
82        let mut email = raw.email;
83        let mut description = raw.description;
84
85        if let Some(extra) = raw.extra {
86            if version == default_version() && !extra.version.is_empty() {
87                version = extra.version;
88            }
89            if author == default_author() && !extra.author.is_empty() {
90                author = extra.author;
91            }
92            if email.is_empty() && !extra.email.is_empty() {
93                email = extra.email;
94            }
95            if description.is_empty() && !extra.description.is_empty() {
96                description = extra.description;
97            }
98        }
99
100        Ok(Self {
101            name: raw.name,
102            version,
103            author,
104            email,
105            description,
106            abi: raw.abi,
107            permissions: raw.permissions,
108            trusts: raw.trusts,
109            supported_standards: raw.supported_standards,
110        })
111    }
112}
113
114/// Neo N3 Contract ABI
115#[derive(Debug, Clone, PartialEq, Eq)]
116#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
117pub struct NeoContractABI {
118    pub hash: String,
119    pub methods: Vec<NeoContractMethod>,
120    pub events: Vec<NeoContractEvent>,
121}
122
123// NOTE: this SDK-side, (de)serialize-capable ABI type mirrors the compiler's
124// serialize-only `ManifestMethod`/`ManifestParameter` in `wasm-neovm`. Both
125// model the same Neo N3 ABI spec and must evolve together; a shared `neo-abi`
126// crate is the tracked path to unifying them.
127
128/// Neo N3 Contract Method
129#[derive(Debug, Clone, PartialEq, Eq)]
130#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
131pub struct NeoContractMethod {
132    pub name: String,
133    pub parameters: Vec<NeoContractParameter>,
134    #[cfg_attr(feature = "serde", serde(rename = "returntype"))]
135    pub return_type: String,
136    pub offset: u32,
137    pub safe: bool,
138}
139
140/// Neo N3 Contract Event
141#[derive(Debug, Clone, PartialEq, Eq)]
142#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
143pub struct NeoContractEvent {
144    pub name: String,
145    pub parameters: Vec<NeoContractParameter>,
146}
147
148/// Neo N3 Contract Parameter
149#[derive(Debug, Clone, PartialEq, Eq)]
150#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
151pub struct NeoContractParameter {
152    pub name: String,
153    pub r#type: String,
154}
155
156/// Neo N3 Contract Permission
157#[derive(Debug, Clone, PartialEq, Eq)]
158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
159pub struct NeoContractPermission {
160    pub contract: String,
161    pub methods: Vec<String>,
162}