Skip to main content

iota_json_rpc_types/
object_changes.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::fmt::{Display, Formatter, Result};
6
7use iota_sdk_types::{Address, ObjectDigest, ObjectId, ObjectReference, Owner, StructTag, Version};
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use serde_with::serde_as;
11
12use crate::{
13    iota_owner::OwnerSchema,
14    iota_primitives::{
15        Address as AddressSchema, Base58 as Base58Schema, ObjectId as ObjectIdSchema,
16        SequenceNumberString as SequenceNumberStringSchema, StructTag as StructTagSchema,
17    },
18};
19
20/// ObjectChange are derived from the object mutations in the TransactionEffect
21/// to provide richer object information.
22#[serde_as]
23#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq, Eq)]
24#[serde(rename_all = "camelCase", tag = "type")]
25pub enum ObjectChange {
26    /// Module published
27    #[serde(rename_all = "camelCase")]
28    Published {
29        #[serde_as(as = "ObjectIdSchema")]
30        #[schemars(with = "ObjectIdSchema")]
31        package_id: ObjectId,
32        #[schemars(with = "SequenceNumberStringSchema")]
33        #[serde_as(as = "SequenceNumberStringSchema")]
34        version: Version,
35        #[serde_as(as = "Base58Schema")]
36        #[schemars(with = "Base58Schema")]
37        digest: ObjectDigest,
38        modules: Vec<String>,
39    },
40    /// Transfer objects to new address / wrap in another object
41    #[serde(rename_all = "camelCase")]
42    Transferred {
43        #[serde_as(as = "AddressSchema")]
44        #[schemars(with = "AddressSchema")]
45        sender: Address,
46        #[schemars(with = "OwnerSchema")]
47        #[serde_as(as = "OwnerSchema")]
48        recipient: Owner,
49        #[schemars(with = "StructTagSchema")]
50        #[serde_as(as = "StructTagSchema")]
51        object_type: StructTag,
52        #[serde_as(as = "ObjectIdSchema")]
53        #[schemars(with = "ObjectIdSchema")]
54        object_id: ObjectId,
55        #[schemars(with = "SequenceNumberStringSchema")]
56        #[serde_as(as = "SequenceNumberStringSchema")]
57        version: Version,
58        #[serde_as(as = "Base58Schema")]
59        #[schemars(with = "Base58Schema")]
60        digest: ObjectDigest,
61    },
62    /// Object mutated.
63    #[serde(rename_all = "camelCase")]
64    Mutated {
65        #[serde_as(as = "AddressSchema")]
66        #[schemars(with = "AddressSchema")]
67        sender: Address,
68        #[schemars(with = "OwnerSchema")]
69        #[serde_as(as = "OwnerSchema")]
70        owner: Owner,
71        #[schemars(with = "StructTagSchema")]
72        #[serde_as(as = "StructTagSchema")]
73        object_type: StructTag,
74        #[serde_as(as = "ObjectIdSchema")]
75        #[schemars(with = "ObjectIdSchema")]
76        object_id: ObjectId,
77        #[schemars(with = "SequenceNumberStringSchema")]
78        #[serde_as(as = "SequenceNumberStringSchema")]
79        version: Version,
80        #[schemars(with = "SequenceNumberStringSchema")]
81        #[serde_as(as = "SequenceNumberStringSchema")]
82        previous_version: Version,
83        #[serde_as(as = "Base58Schema")]
84        #[schemars(with = "Base58Schema")]
85        digest: ObjectDigest,
86    },
87    /// Delete object
88    #[serde(rename_all = "camelCase")]
89    Deleted {
90        #[serde_as(as = "AddressSchema")]
91        #[schemars(with = "AddressSchema")]
92        sender: Address,
93        #[schemars(with = "StructTagSchema")]
94        #[serde_as(as = "StructTagSchema")]
95        object_type: StructTag,
96        #[serde_as(as = "ObjectIdSchema")]
97        #[schemars(with = "ObjectIdSchema")]
98        object_id: ObjectId,
99        #[schemars(with = "SequenceNumberStringSchema")]
100        #[serde_as(as = "SequenceNumberStringSchema")]
101        version: Version,
102    },
103    /// Wrapped object
104    #[serde(rename_all = "camelCase")]
105    Wrapped {
106        #[serde_as(as = "AddressSchema")]
107        #[schemars(with = "AddressSchema")]
108        sender: Address,
109        #[schemars(with = "StructTagSchema")]
110        #[serde_as(as = "StructTagSchema")]
111        object_type: StructTag,
112        #[serde_as(as = "ObjectIdSchema")]
113        #[schemars(with = "ObjectIdSchema")]
114        object_id: ObjectId,
115        #[schemars(with = "SequenceNumberStringSchema")]
116        #[serde_as(as = "SequenceNumberStringSchema")]
117        version: Version,
118    },
119    /// Unwrapped object
120    #[serde(rename_all = "camelCase")]
121    Unwrapped {
122        #[serde_as(as = "AddressSchema")]
123        #[schemars(with = "AddressSchema")]
124        sender: Address,
125        #[schemars(with = "OwnerSchema")]
126        #[serde_as(as = "OwnerSchema")]
127        owner: Owner,
128        #[schemars(with = "StructTagSchema")]
129        #[serde_as(as = "StructTagSchema")]
130        object_type: StructTag,
131        #[serde_as(as = "ObjectIdSchema")]
132        #[schemars(with = "ObjectIdSchema")]
133        object_id: ObjectId,
134        #[schemars(with = "SequenceNumberStringSchema")]
135        #[serde_as(as = "SequenceNumberStringSchema")]
136        version: Version,
137        #[serde_as(as = "Base58Schema")]
138        #[schemars(with = "Base58Schema")]
139        digest: ObjectDigest,
140    },
141    /// New object creation
142    #[serde(rename_all = "camelCase")]
143    Created {
144        #[serde_as(as = "AddressSchema")]
145        #[schemars(with = "AddressSchema")]
146        sender: Address,
147        #[schemars(with = "OwnerSchema")]
148        #[serde_as(as = "OwnerSchema")]
149        owner: Owner,
150        #[schemars(with = "StructTagSchema")]
151        #[serde_as(as = "StructTagSchema")]
152        object_type: StructTag,
153        #[serde_as(as = "ObjectIdSchema")]
154        #[schemars(with = "ObjectIdSchema")]
155        object_id: ObjectId,
156        #[schemars(with = "SequenceNumberStringSchema")]
157        #[serde_as(as = "SequenceNumberStringSchema")]
158        version: Version,
159        #[serde_as(as = "Base58Schema")]
160        #[schemars(with = "Base58Schema")]
161        digest: ObjectDigest,
162    },
163}
164
165impl ObjectChange {
166    pub fn object_id(&self) -> ObjectId {
167        match self {
168            ObjectChange::Published { package_id, .. } => *package_id,
169            ObjectChange::Transferred { object_id, .. }
170            | ObjectChange::Mutated { object_id, .. }
171            | ObjectChange::Deleted { object_id, .. }
172            | ObjectChange::Wrapped { object_id, .. }
173            | ObjectChange::Unwrapped { object_id, .. }
174            | ObjectChange::Created { object_id, .. } => *object_id,
175        }
176    }
177
178    pub fn object_ref(&self) -> ObjectReference {
179        match self {
180            ObjectChange::Published {
181                package_id,
182                version,
183                digest,
184                ..
185            } => ObjectReference::new(*package_id, *version, *digest),
186            ObjectChange::Transferred {
187                object_id,
188                version,
189                digest,
190                ..
191            }
192            | ObjectChange::Mutated {
193                object_id,
194                version,
195                digest,
196                ..
197            }
198            | ObjectChange::Unwrapped {
199                object_id,
200                version,
201                digest,
202                ..
203            }
204            | ObjectChange::Created {
205                object_id,
206                version,
207                digest,
208                ..
209            } => ObjectReference::new(*object_id, *version, *digest),
210            ObjectChange::Deleted {
211                object_id, version, ..
212            } => ObjectReference::new(*object_id, *version, ObjectDigest::OBJECT_DELETED),
213            ObjectChange::Wrapped {
214                object_id, version, ..
215            } => ObjectReference::new(*object_id, *version, ObjectDigest::OBJECT_WRAPPED),
216        }
217    }
218
219    pub fn mask_for_test(&mut self, new_version: Version, new_digest: ObjectDigest) {
220        match self {
221            ObjectChange::Published {
222                version, digest, ..
223            }
224            | ObjectChange::Transferred {
225                version, digest, ..
226            }
227            | ObjectChange::Mutated {
228                version, digest, ..
229            }
230            | ObjectChange::Unwrapped {
231                version, digest, ..
232            }
233            | ObjectChange::Created {
234                version, digest, ..
235            } => {
236                *version = new_version;
237                *digest = new_digest
238            }
239            ObjectChange::Deleted { version, .. } | ObjectChange::Wrapped { version, .. } => {
240                *version = new_version
241            }
242        }
243    }
244}
245
246impl Display for ObjectChange {
247    fn fmt(&self, f: &mut Formatter) -> Result {
248        match self {
249            ObjectChange::Published {
250                package_id,
251                version,
252                digest,
253                modules,
254            } => {
255                write!(
256                    f,
257                    " ┌──\n │ PackageID: {} \n │ Version: {} \n │ Digest: {}\n │ Modules: {}\n └──",
258                    package_id,
259                    version,
260                    digest,
261                    modules.join(", ")
262                )
263            }
264            ObjectChange::Transferred {
265                sender,
266                recipient,
267                object_type,
268                object_id,
269                version,
270                digest,
271            } => {
272                write!(
273                    f,
274                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Recipient: {recipient}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
275                )
276            }
277            ObjectChange::Mutated {
278                sender,
279                owner,
280                object_type,
281                object_id,
282                version,
283                previous_version: _,
284                digest,
285            } => {
286                write!(
287                    f,
288                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
289                )
290            }
291            ObjectChange::Deleted {
292                sender,
293                object_type,
294                object_id,
295                version,
296            } => {
297                write!(
298                    f,
299                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
300                )
301            }
302            ObjectChange::Wrapped {
303                sender,
304                object_type,
305                object_id,
306                version,
307            } => {
308                write!(
309                    f,
310                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
311                )
312            }
313            ObjectChange::Unwrapped {
314                sender,
315                owner,
316                object_type,
317                object_id,
318                version,
319                digest,
320            } => {
321                write!(
322                    f,
323                    " ┌──\n │ ObjectId: {}\n │ Sender: {} \n │ Owner: {}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
324                    object_id,
325                    sender,
326                    owner,
327                    object_type,
328                    version.as_u64(),
329                    digest
330                )
331            }
332            ObjectChange::Created {
333                sender,
334                owner,
335                object_type,
336                object_id,
337                version,
338                digest,
339            } => {
340                write!(
341                    f,
342                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
343                )
344            }
345        }
346    }
347}