1use alloc::boxed::Box;
3use alloc::{vec, vec::Vec};
4use casper_types::{CLType, CLTyped, Parameter};
5
6pub enum EntryPoint {
8 Regular {
10 name: &'static str,
12 args: Vec<Option<Parameter>>,
14 ret_ty: CLType,
16 is_non_reentrant: bool,
18 is_payable: bool
20 },
21 Constructor {
23 args: Vec<Option<Parameter>>
25 },
26 Template {
28 name: &'static str,
30 args: Vec<Option<Parameter>>,
32 ret_ty: CLType
34 },
35 Factory {
37 args: Vec<Option<Parameter>>
39 },
40 FactoryUpgrade {
42 args: Vec<Option<Parameter>>
44 },
45 FactoryBatchUpgrade,
47 Upgrader {
49 args: Vec<Option<Parameter>>
51 }
52}
53
54pub trait EntityEntryPointsExt {
56 fn add<T: Into<casper_types::EntityEntryPoint>>(&mut self, ep: T);
58}
59
60impl EntityEntryPointsExt for casper_types::EntryPoints {
61 fn add<T: Into<casper_types::EntityEntryPoint>>(&mut self, ep: T) {
62 self.add_entry_point(ep.into());
63 }
64}
65
66impl From<EntryPoint> for casper_types::EntityEntryPoint {
67 fn from(val: EntryPoint) -> Self {
68 match val {
69 EntryPoint::Regular {
70 name, args, ret_ty, ..
71 } => entry_point(name, args, ret_ty),
72 EntryPoint::Constructor { args } => constructor(args),
73 EntryPoint::Template { name, args, ret_ty } => template(name, args, ret_ty),
74 EntryPoint::Factory { args } => factory(args),
75 EntryPoint::Upgrader { args } => upgrader(args),
76 EntryPoint::FactoryUpgrade { args } => factory_upgrade(args),
77 EntryPoint::FactoryBatchUpgrade => factory_batch_upgrade()
78 }
79 }
80}
81
82impl TryFrom<EntryPoint> for crate::contract_def::Entrypoint {
83 type Error = &'static str;
84
85 fn try_from(val: EntryPoint) -> Result<Self, Self::Error> {
86 match val {
87 EntryPoint::Regular { name, args, ret_ty, is_non_reentrant, is_payable } => Ok(crate::contract_def::Entrypoint {
88 name: crate::prelude::string::String::from(name),
89 args: convert_args(args),
90 is_mutable: true,
91 return_ty: ret_ty,
92 ty: crate::contract_def::EntrypointType::Public,
93 attributes: match (is_non_reentrant, is_payable) {
94 (true, true) => vec![
95 crate::contract_def::EntrypointAttribute::NonReentrant,
96 crate::contract_def::EntrypointAttribute::Payable
97 ],
98 (true, false) => vec![
99 crate::contract_def::EntrypointAttribute::NonReentrant
100 ],
101 (false, true) => vec![
102 crate::contract_def::EntrypointAttribute::Payable
103 ],
104 (false, false) => vec![]
105 }
106 }),
107 EntryPoint::Constructor { args } => Ok(crate::contract_def::Entrypoint {
108 name: crate::prelude::String::from("init"),
109 args: convert_args(args),
110 is_mutable: true,
111 return_ty: <() as crate::casper_types::CLTyped>::cl_type(),
112 ty: crate::contract_def::EntrypointType::Constructor,
113 attributes: crate::prelude::vec![]
114 }),
115 EntryPoint::Factory { args } => Ok(crate::contract_def::Entrypoint {
116 name: crate::prelude::string::String::from("new_contract"),
117 args: convert_args(args),
118 is_mutable: true,
119 return_ty: <(crate::prelude::Address, crate::casper_types::URef) as crate::casper_types::CLTyped>::cl_type(),
120 ty: crate::contract_def::EntrypointType::Public,
121 attributes: crate::prelude::vec![]
122 }),
123 EntryPoint::FactoryUpgrade { args } => Ok(crate::contract_def::Entrypoint {
124 name: crate::prelude::String::from("upgrade_child_contract"),
125 args: convert_args(args),
126 is_mutable: true,
127 return_ty: <() as crate::casper_types::CLTyped>::cl_type(),
128 ty: crate::contract_def::EntrypointType::Public,
129 attributes: crate::prelude::vec![]
130 }),
131 EntryPoint::FactoryBatchUpgrade => Ok(crate::contract_def::Entrypoint {
132 name: crate::prelude::String::from("batch_upgrade_child_contract"),
133 args: crate::prelude::vec![
134 crate::contract_def::Argument {
135 name: crate::prelude::String::from("args"),
136 ty: Vec::<u8>::cl_type(),
137 is_ref: false,
138 is_slice: false,
139 is_required: true
140 }
141 ],
142 is_mutable: true,
143 return_ty: <() as crate::casper_types::CLTyped>::cl_type(),
144 ty: crate::contract_def::EntrypointType::Public,
145 attributes: crate::prelude::vec![]
146 }),
147 _ => Err("Conversion not implemented for this entry point type"),
148 }
149 }
150}
151
152fn convert_args(args: Vec<Option<Parameter>>) -> Vec<crate::contract_def::Argument> {
153 args.into_iter()
154 .flatten()
155 .map(|p| crate::contract_def::Argument {
156 name: crate::prelude::string::String::from(p.name()),
157 ty: p.cl_type().clone(),
158 is_ref: false,
159 is_slice: false,
160 is_required: true
161 })
162 .collect()
163}
164
165fn entry_point(
166 name: &str,
167 args: Vec<Option<Parameter>>,
168 ret_ty: CLType
169) -> casper_types::EntityEntryPoint {
170 casper_types::EntityEntryPoint::new(
171 name,
172 args.into_iter().flatten().collect(),
173 ret_ty,
174 casper_types::EntryPointAccess::Public,
175 casper_types::EntryPointType::Called,
176 casper_types::EntryPointPayment::Caller
177 )
178}
179
180fn constructor(args: Vec<Option<Parameter>>) -> casper_types::EntityEntryPoint {
181 casper_types::EntityEntryPoint::new(
182 "init",
183 args.into_iter().flatten().collect(),
184 CLType::Unit,
185 casper_types::EntryPointAccess::Groups(vec![casper_types::Group::new("constructor_group")]),
186 casper_types::EntryPointType::Called,
187 casper_types::EntryPointPayment::Caller
188 )
189}
190
191fn template(
192 name: &str,
193 args: Vec<Option<Parameter>>,
194 ret_ty: CLType
195) -> casper_types::EntityEntryPoint {
196 casper_types::EntityEntryPoint::new(
197 name,
198 args.into_iter().flatten().collect(),
199 ret_ty,
200 casper_types::EntryPointAccess::Template,
201 casper_types::EntryPointType::Called,
202 casper_types::EntryPointPayment::Caller
203 )
204}
205
206fn factory(args: Vec<Option<Parameter>>) -> casper_types::EntityEntryPoint {
207 casper_types::EntityEntryPoint::new(
208 "new_contract",
209 args.into_iter().flatten().collect(),
210 CLType::Tuple2([Box::new(CLType::Key), Box::new(CLType::URef)]),
211 casper_types::EntryPointAccess::Public,
212 casper_types::EntryPointType::Factory,
213 casper_types::EntryPointPayment::Caller
214 )
215}
216
217fn factory_upgrade(args: Vec<Option<Parameter>>) -> casper_types::EntityEntryPoint {
218 casper_types::EntityEntryPoint::new(
219 "upgrade_child_contract",
220 args.into_iter().flatten().collect(),
221 CLType::Unit,
222 casper_types::EntryPointAccess::Groups(vec![casper_types::Group::new("factory_group")]),
223 casper_types::EntryPointType::Called,
224 casper_types::EntryPointPayment::Caller
225 )
226}
227
228fn factory_batch_upgrade() -> casper_types::EntityEntryPoint {
229 casper_types::EntityEntryPoint::new(
230 "batch_upgrade_child_contract",
231 vec![casper_types::Parameter::new("args", Vec::<u8>::cl_type())],
232 CLType::Unit,
233 casper_types::EntryPointAccess::Groups(vec![casper_types::Group::new("factory_group")]),
234 casper_types::EntryPointType::Called,
235 casper_types::EntryPointPayment::Caller
236 )
237}
238
239fn upgrader(args: Vec<Option<Parameter>>) -> casper_types::EntityEntryPoint {
240 casper_types::EntityEntryPoint::new(
241 "upgrade",
242 args.into_iter().flatten().collect(),
243 CLType::Unit,
244 casper_types::EntryPointAccess::Groups(vec![casper_types::Group::new("upgrader_group")]),
245 casper_types::EntryPointType::Called,
246 casper_types::EntryPointPayment::Caller
247 )
248}