iota_indexer/apis/
move_utils.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::collections::BTreeMap;
6
7use async_trait::async_trait;
8use iota_json_rpc::{IotaRpcModule, error::IotaRpcInputError};
9use iota_json_rpc_api::MoveUtilsServer;
10use iota_json_rpc_types::{
11    IotaMoveNormalizedFunction, IotaMoveNormalizedModule, IotaMoveNormalizedStruct,
12    IotaMoveNormalizedType, MoveFunctionArgType, ObjectValueKind,
13};
14use iota_open_rpc::Module;
15use iota_types::base_types::ObjectID;
16use jsonrpsee::{RpcModule, core::RpcResult};
17use move_binary_format::normalized::Module as NormalizedModule;
18
19use crate::indexer_reader::IndexerReader;
20
21pub struct MoveUtilsApi {
22    inner: IndexerReader,
23}
24
25impl MoveUtilsApi {
26    pub fn new(inner: IndexerReader) -> Self {
27        Self { inner }
28    }
29}
30
31#[async_trait]
32impl MoveUtilsServer for MoveUtilsApi {
33    async fn get_normalized_move_modules_by_package(
34        &self,
35        package_id: ObjectID,
36    ) -> RpcResult<BTreeMap<String, IotaMoveNormalizedModule>> {
37        let resolver_modules = self.inner.get_package(package_id).await?.modules().clone();
38        let iota_normalized_modules = resolver_modules
39            .into_iter()
40            .map(|(k, v)| (k, NormalizedModule::new(v.bytecode()).into()))
41            .collect::<BTreeMap<String, IotaMoveNormalizedModule>>();
42        Ok(iota_normalized_modules)
43    }
44
45    async fn get_normalized_move_module(
46        &self,
47        package: ObjectID,
48        module_name: String,
49    ) -> RpcResult<IotaMoveNormalizedModule> {
50        let mut modules = self.get_normalized_move_modules_by_package(package).await?;
51        let module = modules.remove(&module_name).ok_or_else(|| {
52            IotaRpcInputError::GenericNotFound(format!(
53                "No module was found with name {module_name}",
54            ))
55        })?;
56        Ok(module)
57    }
58
59    async fn get_normalized_move_struct(
60        &self,
61        package: ObjectID,
62        module_name: String,
63        struct_name: String,
64    ) -> RpcResult<IotaMoveNormalizedStruct> {
65        let mut module = self
66            .get_normalized_move_module(package, module_name)
67            .await?;
68        module
69            .structs
70            .remove(&struct_name)
71            .ok_or_else(|| {
72                IotaRpcInputError::GenericNotFound(format!(
73                    "No struct was found with struct name {struct_name}"
74                ))
75            })
76            .map_err(Into::into)
77    }
78
79    async fn get_normalized_move_function(
80        &self,
81        package: ObjectID,
82        module_name: String,
83        function_name: String,
84    ) -> RpcResult<IotaMoveNormalizedFunction> {
85        let mut module = self
86            .get_normalized_move_module(package, module_name)
87            .await?;
88        module
89            .exposed_functions
90            .remove(&function_name)
91            .ok_or_else(|| {
92                IotaRpcInputError::GenericNotFound(format!(
93                    "No function was found with function name {function_name}",
94                ))
95            })
96            .map_err(Into::into)
97    }
98
99    async fn get_move_function_arg_types(
100        &self,
101        package: ObjectID,
102        module: String,
103        function: String,
104    ) -> RpcResult<Vec<MoveFunctionArgType>> {
105        let function = self
106            .get_normalized_move_function(package, module, function)
107            .await?;
108        let args = function
109            .parameters
110            .iter()
111            .map(|p| match p {
112                IotaMoveNormalizedType::Struct { .. } => {
113                    MoveFunctionArgType::Object(ObjectValueKind::ByValue)
114                }
115                IotaMoveNormalizedType::Vector(_) => {
116                    MoveFunctionArgType::Object(ObjectValueKind::ByValue)
117                }
118                IotaMoveNormalizedType::Reference(_) => {
119                    MoveFunctionArgType::Object(ObjectValueKind::ByImmutableReference)
120                }
121                IotaMoveNormalizedType::MutableReference(_) => {
122                    MoveFunctionArgType::Object(ObjectValueKind::ByMutableReference)
123                }
124                _ => MoveFunctionArgType::Pure,
125            })
126            .collect::<Vec<MoveFunctionArgType>>();
127        Ok(args)
128    }
129}
130
131impl IotaRpcModule for MoveUtilsApi {
132    fn rpc(self) -> RpcModule<Self> {
133        self.into_rpc()
134    }
135
136    fn rpc_doc_module() -> Module {
137        iota_json_rpc_api::MoveUtilsOpenRpc::module_doc()
138    }
139}