starknet_rust_providers/sequencer/models/
contract.rs1use std::io::Write;
2
3use flate2::{write::GzEncoder, Compression};
4use serde::{Deserialize, Deserializer, Serialize};
5use serde_with::serde_as;
6use starknet_rust_core::{
7 serde::{byte_array::base64::serialize as base64_ser, unsigned_field_element::UfeHex},
8 types::{
9 contract::{
10 legacy::{LegacyContractClass, RawLegacyAbiEntry, RawLegacyEntryPoints},
11 CompressProgramError,
12 },
13 EntryPointsByType, Felt, FlattenedSierraClass,
14 },
15};
16
17#[derive(Debug, Serialize)]
18#[serde(untagged)]
19#[allow(clippy::large_enum_variant)]
20pub enum DeployedClass {
21 SierraClass(FlattenedSierraClass),
22 LegacyClass(LegacyContractClass),
23}
24
25#[serde_as]
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[cfg_attr(feature = "no_unknown_fields", serde(deny_unknown_fields))]
28pub struct CompressedSierraClass {
29 #[serde(serialize_with = "base64_ser")]
30 pub sierra_program: Vec<u8>,
31 pub contract_class_version: String,
32 pub entry_points_by_type: EntryPointsByType,
33 pub abi: String,
34}
35
36#[derive(Debug, Serialize, Clone)]
39pub struct CompressedLegacyContractClass {
40 #[serde(serialize_with = "base64_ser")]
41 pub program: Vec<u8>,
42 pub entry_points_by_type: RawLegacyEntryPoints,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub abi: Option<Vec<RawLegacyAbiEntry>>,
45}
46
47#[derive(Debug, thiserror::Error)]
48pub enum DecompressProgramError {
49 #[error("json deserialization error: {0}")]
50 Json(serde_json::Error),
51 #[error("decompression io error: {0}")]
52 Io(std::io::Error),
53}
54
55impl<'de> Deserialize<'de> for DeployedClass {
58 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59 where
60 D: Deserializer<'de>,
61 {
62 let temp_value = serde_json::Value::deserialize(deserializer)?;
63 if let Ok(value) = FlattenedSierraClass::deserialize(&temp_value) {
64 return Ok(Self::SierraClass(value));
65 }
66 if let Ok(value) = LegacyContractClass::deserialize(&temp_value) {
67 return Ok(Self::LegacyClass(value));
68 }
69 Err(serde::de::Error::custom(
70 "data did not match any variant of enum DeployedClass",
71 ))
72 }
73}
74
75impl CompressedSierraClass {
76 pub fn from_flattened(
77 flattened_class: &FlattenedSierraClass,
78 ) -> Result<Self, DecompressProgramError> {
79 #[serde_as]
80 #[derive(Serialize)]
81 struct SierraProgram<'a>(#[serde_as(as = "Vec<UfeHex>")] &'a Vec<Felt>);
82
83 let program_json = serde_json::to_string(&SierraProgram(&flattened_class.sierra_program))
84 .map_err(DecompressProgramError::Json)?;
85
86 let mut gzip_encoder = GzEncoder::new(Vec::new(), Compression::best());
88 gzip_encoder
89 .write_all(program_json.as_bytes())
90 .map_err(DecompressProgramError::Io)?;
91
92 let compressed_program = gzip_encoder.finish().map_err(DecompressProgramError::Io)?;
93
94 Ok(Self {
95 sierra_program: compressed_program,
96 contract_class_version: flattened_class.contract_class_version.clone(),
97 entry_points_by_type: flattened_class.entry_points_by_type.clone(),
98 abi: flattened_class.abi.clone(),
99 })
100 }
101}