1mod to_tpk;
17mod verify;
18
19use crate::{Identifier, Plaintext, ProgramID, Record, Value, compute_function_id};
20use snarkvm_circuit_account::Signature;
21use snarkvm_circuit_network::Aleo;
22use snarkvm_circuit_types::{Address, Boolean, Field, Group, U16, environment::prelude::*};
23
24pub enum InputID<A: Aleo> {
25 Constant(Field<A>),
27 Public(Field<A>),
29 Private(Field<A>),
31 Record(Field<A>, Box<Group<A>>, Field<A>, Field<A>, Field<A>),
33 ExternalRecord(Field<A>),
35 DynamicRecord(Field<A>),
37}
38
39impl<A: Aleo> Inject for InputID<A> {
40 type Primitive = console::InputID<A::Network>;
41
42 fn new(_: Mode, input: Self::Primitive) -> Self {
44 match input {
45 console::InputID::Constant(field) => Self::Constant(Field::new(Mode::Public, field)),
47 console::InputID::Public(field) => Self::Public(Field::new(Mode::Public, field)),
49 console::InputID::Private(field) => Self::Private(Field::new(Mode::Public, field)),
51 console::InputID::Record(commitment, gamma, record_view_key, serial_number, tag) => Self::Record(
53 Field::new(Mode::Private, commitment),
54 Box::new(Group::new(Mode::Private, gamma)),
55 Field::new(Mode::Private, record_view_key),
56 Field::new(Mode::Public, serial_number),
57 Field::new(Mode::Public, tag),
58 ),
59 console::InputID::ExternalRecord(field) => Self::ExternalRecord(Field::new(Mode::Public, field)),
61 console::InputID::DynamicRecord(field) => Self::DynamicRecord(Field::new(Mode::Public, field)),
63 }
64 }
65}
66
67impl<A: Aleo> Eject for InputID<A> {
68 type Primitive = console::InputID<A::Network>;
69
70 fn eject_mode(&self) -> Mode {
72 match self {
73 Self::Constant(field) => field.eject_mode(),
74 Self::Public(field) => field.eject_mode(),
75 Self::Private(field) => field.eject_mode(),
76 Self::Record(commitment, gamma, record_view_key, serial_number, tag) => {
77 Mode::combine(commitment.eject_mode(), [
78 gamma.eject_mode(),
79 record_view_key.eject_mode(),
80 serial_number.eject_mode(),
81 tag.eject_mode(),
82 ])
83 }
84 Self::ExternalRecord(field) => field.eject_mode(),
85 Self::DynamicRecord(field) => field.eject_mode(),
86 }
87 }
88
89 fn eject_value(&self) -> Self::Primitive {
91 match self {
92 Self::Constant(field) => console::InputID::Constant(field.eject_value()),
93 Self::Public(field) => console::InputID::Public(field.eject_value()),
94 Self::Private(field) => console::InputID::Private(field.eject_value()),
95 Self::Record(commitment, gamma, record_view_key, serial_number, tag) => console::InputID::Record(
96 commitment.eject_value(),
97 gamma.eject_value(),
98 record_view_key.eject_value(),
99 serial_number.eject_value(),
100 tag.eject_value(),
101 ),
102 Self::ExternalRecord(field) => console::InputID::ExternalRecord(field.eject_value()),
103 Self::DynamicRecord(field) => console::InputID::DynamicRecord(field.eject_value()),
104 }
105 }
106}
107
108impl<A: Aleo> ToFields for InputID<A> {
109 type Field = Field<A>;
110
111 fn to_fields(&self) -> Vec<Self::Field> {
113 match self {
114 InputID::Constant(field) => vec![field.clone()],
115 InputID::Public(field) => vec![field.clone()],
116 InputID::Private(field) => vec![field.clone()],
117 InputID::Record(commitment, gamma, record_view_key, serial_number, tag) => {
118 vec![
119 commitment.clone(),
120 gamma.to_x_coordinate(),
121 record_view_key.clone(),
122 serial_number.clone(),
123 tag.clone(),
124 ]
125 }
126 InputID::ExternalRecord(field) => vec![field.clone()],
127 InputID::DynamicRecord(field) => vec![field.clone()],
128 }
129 }
130}
131
132pub struct Request<A: Aleo> {
133 signer: Address<A>,
135 network_id: U16<A>,
137 program_id: ProgramID<A>,
139 function_name: Identifier<A>,
141 input_ids: Vec<InputID<A>>,
143 inputs: Vec<Value<A>>,
145 signature: Signature<A>,
147 sk_tag: Field<A>,
149 tvk: Field<A>,
151 tcm: Field<A>,
153 scm: Field<A>,
155 is_dynamic: bool,
157}
158
159impl<A: Aleo> Inject for Request<A> {
160 type Primitive = console::Request<A::Network>;
161
162 fn new(mode: Mode, request: Self::Primitive) -> Self {
164 let tcm = Field::new(Mode::Public, *request.tcm());
166
167 let scm = Field::new(Mode::Public, *request.scm());
169
170 let inputs = match request
172 .input_ids()
173 .iter()
174 .zip_eq(request.inputs())
175 .map(|(input_id, input)| {
176 match input_id {
177 console::InputID::Constant(..) => {
179 let input = Value::new(Mode::Constant, input.clone());
181 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
183 Ok(input)
185 }
186 console::InputID::Public(..) => {
188 let input = Value::new(Mode::Private, input.clone());
190 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
192 Ok(input)
194 }
195 console::InputID::Private(..) => {
197 let input = Value::new(Mode::Private, input.clone());
199 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
201 Ok(input)
203 }
204 console::InputID::Record(..) => {
206 let input = Value::new(Mode::Private, input.clone());
208 ensure!(matches!(input, Value::Record(..)), "Expected a record input");
210 Ok(input)
212 }
213 console::InputID::ExternalRecord(..) => {
215 let input = Value::new(Mode::Private, input.clone());
217 ensure!(matches!(input, Value::Record(..)), "Expected an external record input");
219 Ok(input)
221 }
222 console::InputID::DynamicRecord(..) => {
224 let input = Value::new(Mode::Private, input.clone());
226 ensure!(matches!(input, Value::DynamicRecord(..)), "Expected a dynamic record input");
228 Ok(input)
230 }
231 }
232 })
233 .collect::<Result<Vec<_>, _>>()
234 {
235 Ok(inputs) => inputs,
236 Err(error) => A::halt(format!("{error}")),
237 };
238
239 Self {
240 signer: Address::new(mode, *request.signer()),
241 network_id: U16::new(Mode::Constant, *request.network_id()),
242 program_id: ProgramID::constant(*request.program_id()),
243 function_name: Identifier::constant(*request.function_name()),
244 input_ids: request.input_ids().iter().map(|input_id| InputID::new(Mode::Public, *input_id)).collect(),
245 inputs,
246 signature: Signature::new(mode, *request.signature()),
247 sk_tag: Field::new(mode, *request.sk_tag()),
248 tvk: Field::new(mode, *request.tvk()),
249 tcm,
250 scm,
251 is_dynamic: request.is_dynamic(),
252 }
253 }
254}
255
256impl<A: Aleo> Request<A> {
257 pub const fn signer(&self) -> &Address<A> {
259 &self.signer
260 }
261
262 pub const fn network_id(&self) -> &U16<A> {
264 &self.network_id
265 }
266
267 pub const fn program_id(&self) -> &ProgramID<A> {
269 &self.program_id
270 }
271
272 pub const fn function_name(&self) -> &Identifier<A> {
274 &self.function_name
275 }
276
277 pub fn input_ids(&self) -> &[InputID<A>] {
279 &self.input_ids
280 }
281
282 pub fn inputs(&self) -> &[Value<A>] {
284 &self.inputs
285 }
286
287 pub const fn signature(&self) -> &Signature<A> {
289 &self.signature
290 }
291
292 pub const fn sk_tag(&self) -> &Field<A> {
294 &self.sk_tag
295 }
296
297 pub const fn tvk(&self) -> &Field<A> {
299 &self.tvk
300 }
301
302 pub const fn tcm(&self) -> &Field<A> {
304 &self.tcm
305 }
306
307 pub const fn scm(&self) -> &Field<A> {
309 &self.scm
310 }
311
312 pub fn is_dynamic(&self) -> bool {
314 self.is_dynamic
315 }
316}
317
318impl<A: Aleo> Eject for Request<A> {
319 type Primitive = console::Request<A::Network>;
320
321 fn eject_mode(&self) -> Mode {
323 Mode::combine(self.signer.eject_mode(), [
324 self.network_id.eject_mode(),
325 self.program_id.eject_mode(),
326 self.function_name.eject_mode(),
327 self.input_ids.eject_mode(),
328 self.inputs.eject_mode(),
329 self.signature.eject_mode(),
330 self.sk_tag.eject_mode(),
331 self.tvk.eject_mode(),
332 self.tcm.eject_mode(),
333 self.scm.eject_mode(),
334 ])
335 }
336
337 fn eject_value(&self) -> Self::Primitive {
339 Self::Primitive::from((
340 self.signer.eject_value(),
341 self.network_id.eject_value(),
342 self.program_id.eject_value(),
343 self.function_name.eject_value(),
344 self.input_ids.iter().map(|input_id| input_id.eject_value()).collect(),
345 self.inputs.eject_value(),
346 self.signature.eject_value(),
347 self.sk_tag.eject_value(),
348 self.tvk.eject_value(),
349 self.tcm.eject_value(),
350 self.scm.eject_value(),
351 self.is_dynamic,
352 ))
353 }
354}