Skip to main content

sui_indexer_alt_jsonrpc/api/
mod.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use sui_json_rpc_types::ObjectChange as SuiObjectChange;
5use sui_types::base_types::ObjectID;
6use sui_types::base_types::SequenceNumber;
7use sui_types::base_types::SuiAddress;
8use sui_types::digests::ObjectDigest;
9use sui_types::effects::IDOperation;
10use sui_types::object::Object;
11
12pub(crate) mod checkpoints;
13pub(crate) mod coin;
14pub(crate) mod dynamic_fields;
15pub(crate) mod governance;
16pub(crate) mod move_utils;
17pub(crate) mod name_service;
18pub(crate) mod objects;
19pub(crate) mod protocol;
20pub(crate) mod rpc_module;
21pub(crate) mod transactions;
22pub mod write;
23
24/// Map an object change from the effects to a `SuiObjectChange` response type. Returns `None` for
25/// changes that are not visible in the response (created-and-wrapped, unwrapped, unwrapped-then-
26/// deleted, system package upgrades).
27pub(crate) fn to_sui_object_change(
28    sender: SuiAddress,
29    object_id: ObjectID,
30    id_operation: IDOperation,
31    input: Option<(Object, ObjectDigest)>,
32    output: Option<(Object, ObjectDigest)>,
33    lamport_version: SequenceNumber,
34) -> anyhow::Result<Option<SuiObjectChange>> {
35    use IDOperation as ID;
36
37    let change = match (id_operation, &input, &output) {
38        (ID::Created, Some((i, _)), _) => anyhow::bail!(
39            "Unexpected input version {} for object {object_id} created by transaction",
40            i.version().value(),
41        ),
42
43        (ID::Deleted, _, Some((o, _))) => anyhow::bail!(
44            "Unexpected output version {} for object {object_id} deleted by transaction",
45            o.version().value(),
46        ),
47
48        // Created but no output object: created and immediately wrapped.
49        (ID::Created, _, None) => return Ok(None),
50        // No ID change and no input: unwrapped object (or unwrapped-then-deleted).
51        (ID::None, None, _) => return Ok(None),
52        // System package upgrade (happens in-place, not a user-visible change).
53        (ID::None, _, Some((o, _))) if o.is_package() => return Ok(None),
54        // Deleted but no input: unwrapped-then-deleted.
55        (ID::Deleted, None, _) => return Ok(None),
56
57        (ID::Created, _, Some((o, d))) if o.is_package() => SuiObjectChange::Published {
58            package_id: object_id,
59            version: o.version(),
60            digest: *d,
61            modules: o
62                .data
63                .try_as_package()
64                .unwrap() // SAFETY: Match guard checks that the object is a package.
65                .serialized_module_map()
66                .keys()
67                .cloned()
68                .collect(),
69        },
70
71        (ID::Created, _, Some((o, d))) => SuiObjectChange::Created {
72            sender,
73            owner: o.owner().clone(),
74            object_type: o
75                .struct_tag()
76                .ok_or_else(|| anyhow::anyhow!("No type for object {object_id}"))?,
77            object_id,
78            version: o.version(),
79            digest: *d,
80        },
81
82        (ID::None, Some((i, _)), Some((o, od))) if i.owner() != o.owner() => {
83            SuiObjectChange::Transferred {
84                sender,
85                recipient: o.owner().clone(),
86                object_type: o
87                    .struct_tag()
88                    .ok_or_else(|| anyhow::anyhow!("No type for object {object_id}"))?,
89                object_id,
90                version: o.version(),
91                digest: *od,
92            }
93        }
94
95        (ID::None, Some((i, _)), Some((o, od))) => SuiObjectChange::Mutated {
96            sender,
97            owner: o.owner().clone(),
98            object_type: o
99                .struct_tag()
100                .ok_or_else(|| anyhow::anyhow!("No type for object {object_id}"))?,
101            object_id,
102            version: o.version(),
103            previous_version: i.version(),
104            digest: *od,
105        },
106
107        (ID::None, Some((i, _)), None) => SuiObjectChange::Wrapped {
108            sender,
109            object_type: i
110                .struct_tag()
111                .ok_or_else(|| anyhow::anyhow!("No type for object {object_id}"))?,
112            object_id,
113            version: lamport_version,
114        },
115
116        (ID::Deleted, Some((i, _)), None) => SuiObjectChange::Deleted {
117            sender,
118            object_type: i
119                .struct_tag()
120                .ok_or_else(|| anyhow::anyhow!("No type for object {object_id}"))?,
121            object_id,
122            version: lamport_version,
123        },
124    };
125
126    Ok(Some(change))
127}