snarkvm_debug/package/
deploy.rs1use crate::ledger::block::Deployment;
16use snarkvm_console::prelude::DeserializeExt;
17
18use super::*;
19
20pub struct DeployRequest<N: Network> {
21 deployment: Deployment<N>,
22 program_id: ProgramID<N>,
23}
24
25impl<N: Network> DeployRequest<N> {
26 pub fn new(deployment: Deployment<N>, program_id: ProgramID<N>) -> Self {
28 Self { deployment, program_id }
29 }
30
31 pub fn send(&self, endpoint: &str) -> Result<DeployResponse<N>> {
33 Ok(ureq::post(endpoint).send_json(self)?.into_json()?)
34 }
35
36 pub const fn deployment(&self) -> &Deployment<N> {
38 &self.deployment
39 }
40
41 pub const fn program_id(&self) -> &ProgramID<N> {
43 &self.program_id
44 }
45}
46
47impl<N: Network> Serialize for DeployRequest<N> {
48 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
50 let mut request = serializer.serialize_struct("DeployRequest", 2)?;
51 request.serialize_field("deployment", &self.deployment)?;
53 request.serialize_field("program_id", &self.program_id)?;
55 request.end()
56 }
57}
58
59impl<'de, N: Network> Deserialize<'de> for DeployRequest<N> {
60 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
62 let mut request = serde_json::Value::deserialize(deserializer)?;
64 Ok(Self::new(
66 DeserializeExt::take_from_value::<D>(&mut request, "deployment")?,
68 DeserializeExt::take_from_value::<D>(&mut request, "program_id")?,
70 ))
71 }
72}
73
74pub struct DeployResponse<N: Network> {
75 deployment: Deployment<N>,
76}
77
78impl<N: Network> DeployResponse<N> {
79 pub const fn new(deployment: Deployment<N>) -> Self {
81 Self { deployment }
82 }
83
84 pub const fn deployment(&self) -> &Deployment<N> {
86 &self.deployment
87 }
88}
89
90impl<N: Network> Serialize for DeployResponse<N> {
91 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
93 let mut response = serializer.serialize_struct("DeployResponse", 1)?;
94 response.serialize_field("deployment", &self.deployment)?;
95 response.end()
96 }
97}
98
99impl<'de, N: Network> Deserialize<'de> for DeployResponse<N> {
100 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
102 let mut response = serde_json::Value::deserialize(deserializer)?;
104 Ok(Self::new(
106 DeserializeExt::take_from_value::<D>(&mut response, "deployment")?,
108 ))
109 }
110}
111
112impl<N: Network> Package<N> {
113 pub fn deploy<A: crate::circuit::Aleo<Network = N, BaseField = N::Field>>(
114 &self,
115 endpoint: Option<String>,
116 ) -> Result<Deployment<N>> {
117 let program = self.program();
119 let program_id = program.id();
121
122 #[cfg(feature = "aleo-cli")]
123 println!("⏳ Deploying '{}'...\n", program_id.to_string().bold());
124
125 let mut process = Process::<N>::load()?;
127
128 let imports_directory = self.imports_directory();
130 program.imports().keys().try_for_each(|program_id| {
131 let import_program_file = AleoFile::open(&imports_directory, program_id, false)?;
138 process.add_program(import_program_file.program())?;
140 Ok::<_, Error>(())
141 })?;
142
143 let rng = &mut rand::thread_rng();
145 let deployment = process.deploy::<A, _>(program, rng).unwrap();
147
148 match endpoint {
149 Some(ref endpoint) => {
150 let request = DeployRequest::new(deployment, *program_id);
152 let response = request.send(endpoint)?;
154 ensure!(
156 response.deployment.program_id() == program_id,
157 "Program ID mismatch: {} != {program_id}",
158 response.deployment.program_id()
159 );
160 Ok(response.deployment)
161 }
162 None => Ok(deployment),
163 }
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 type CurrentNetwork = snarkvm_console::network::Testnet3;
172 type CurrentAleo = snarkvm_circuit::network::AleoV0;
173
174 #[test]
175 fn test_deploy() {
176 let (directory, package) = crate::package::test_helpers::sample_token_package();
178
179 let deployment = package.deploy::<CurrentAleo>(None).unwrap();
181
182 assert_eq!(<CurrentNetwork as Network>::EDITION, deployment.edition());
184 assert_eq!(package.program().id(), deployment.program_id());
186 assert_eq!(package.program(), deployment.program());
188
189 std::fs::remove_dir_all(directory).unwrap();
191 }
192
193 #[test]
194 fn test_deploy_with_import() {
195 let (directory, package) = crate::package::test_helpers::sample_wallet_package();
197
198 let deployment = package.deploy::<CurrentAleo>(None).unwrap();
200
201 assert_eq!(<CurrentNetwork as Network>::EDITION, deployment.edition());
203 assert_eq!(package.program().id(), deployment.program_id());
205 assert_eq!(package.program(), deployment.program());
207
208 std::fs::remove_dir_all(directory).unwrap();
210 }
211}