iota_indexer/apis/
move_utils.rs1use 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}