iota_indexer/apis/
write_api.rs1use async_trait::async_trait;
6use fastcrypto::encoding::Base64;
7use iota_json_rpc::IotaRpcModule;
8use iota_json_rpc_api::{WriteApiClient, WriteApiServer, error_object_from_rpc};
9use iota_json_rpc_types::{
10 DevInspectArgs, DevInspectResults, DryRunTransactionBlockResponse,
11 IotaTransactionBlockResponse, IotaTransactionBlockResponseOptions,
12};
13use iota_open_rpc::Module;
14use iota_types::{
15 base_types::IotaAddress, iota_serde::BigInt, quorum_driver_types::ExecuteTransactionRequestType,
16};
17use jsonrpsee::{RpcModule, core::RpcResult, http_client::HttpClient};
18
19use crate::{
20 optimistic_indexing::OptimisticTransactionExecutor,
21 types::IotaTransactionBlockResponseWithOptions,
22};
23
24pub(crate) struct WriteApi {
25 fullnode: HttpClient,
26}
27
28pub(crate) struct OptimisticWriteApi {
29 write_api: WriteApi,
30 optimistic_tx_executor: OptimisticTransactionExecutor,
31}
32
33impl WriteApi {
34 pub fn new(fullnode_client: HttpClient) -> Self {
35 Self {
36 fullnode: fullnode_client,
37 }
38 }
39}
40
41impl OptimisticWriteApi {
42 pub fn new(write_api: WriteApi, optimistic_tx_executor: OptimisticTransactionExecutor) -> Self {
43 Self {
44 write_api,
45 optimistic_tx_executor,
46 }
47 }
48}
49
50#[async_trait]
51impl WriteApiServer for WriteApi {
52 async fn execute_transaction_block(
53 &self,
54 tx_bytes: Base64,
55 signatures: Vec<Base64>,
56 options: Option<IotaTransactionBlockResponseOptions>,
57 request_type: Option<ExecuteTransactionRequestType>,
58 ) -> RpcResult<IotaTransactionBlockResponse> {
59 let iota_transaction_response = self
60 .fullnode
61 .execute_transaction_block(tx_bytes, signatures, options.clone(), request_type)
62 .await
63 .map_err(error_object_from_rpc)?;
64 Ok(IotaTransactionBlockResponseWithOptions {
65 response: iota_transaction_response,
66 options: options.unwrap_or_default(),
67 }
68 .into())
69 }
70
71 async fn dev_inspect_transaction_block(
72 &self,
73 sender_address: IotaAddress,
74 tx_bytes: Base64,
75 gas_price: Option<BigInt<u64>>,
76 epoch: Option<BigInt<u64>>,
77 additional_args: Option<DevInspectArgs>,
78 ) -> RpcResult<DevInspectResults> {
79 self.fullnode
80 .dev_inspect_transaction_block(
81 sender_address,
82 tx_bytes,
83 gas_price,
84 epoch,
85 additional_args,
86 )
87 .await
88 .map_err(error_object_from_rpc)
89 }
90
91 async fn dry_run_transaction_block(
92 &self,
93 tx_bytes: Base64,
94 ) -> RpcResult<DryRunTransactionBlockResponse> {
95 self.fullnode
96 .dry_run_transaction_block(tx_bytes)
97 .await
98 .map_err(error_object_from_rpc)
99 }
100}
101
102#[async_trait]
103impl WriteApiServer for OptimisticWriteApi {
104 async fn execute_transaction_block(
105 &self,
106 tx_bytes: Base64,
107 signatures: Vec<Base64>,
108 options: Option<IotaTransactionBlockResponseOptions>,
109 _request_type: Option<ExecuteTransactionRequestType>,
110 ) -> RpcResult<IotaTransactionBlockResponse> {
111 let iota_transaction_response = self
112 .optimistic_tx_executor
113 .execute_and_index_transaction(tx_bytes, signatures, options.clone())
114 .await?;
115 Ok(IotaTransactionBlockResponseWithOptions {
116 response: iota_transaction_response,
117 options: options.unwrap_or_default(),
118 }
119 .into())
120 }
121
122 async fn dev_inspect_transaction_block(
123 &self,
124 sender_address: IotaAddress,
125 tx_bytes: Base64,
126 gas_price: Option<BigInt<u64>>,
127 epoch: Option<BigInt<u64>>,
128 additional_args: Option<DevInspectArgs>,
129 ) -> RpcResult<DevInspectResults> {
130 self.write_api
131 .dev_inspect_transaction_block(
132 sender_address,
133 tx_bytes,
134 gas_price,
135 epoch,
136 additional_args,
137 )
138 .await
139 }
140
141 async fn dry_run_transaction_block(
142 &self,
143 tx_bytes: Base64,
144 ) -> RpcResult<DryRunTransactionBlockResponse> {
145 self.write_api.dry_run_transaction_block(tx_bytes).await
146 }
147}
148
149impl IotaRpcModule for WriteApi {
150 fn rpc(self) -> RpcModule<Self> {
151 self.into_rpc()
152 }
153
154 fn rpc_doc_module() -> Module {
155 iota_json_rpc_api::WriteApiOpenRpc::module_doc()
156 }
157}
158
159impl IotaRpcModule for OptimisticWriteApi {
160 fn rpc(self) -> RpcModule<Self> {
161 self.into_rpc()
162 }
163
164 fn rpc_doc_module() -> Module {
165 iota_json_rpc_api::WriteApiOpenRpc::module_doc()
166 }
167}