iota_indexer/apis/
transaction_builder_api.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use async_trait::async_trait;
6use iota_json_rpc::transaction_builder_api::TransactionBuilderApi as IotaTransactionBuilderApi;
7use iota_json_rpc_types::{IotaObjectDataFilter, IotaObjectDataOptions, IotaObjectResponse};
8use iota_transaction_builder::DataReader;
9use iota_types::{
10    base_types::{IotaAddress, ObjectID, ObjectInfo},
11    object::Object,
12};
13use move_core_types::language_storage::StructTag;
14
15use super::governance_api::GovernanceReadApi;
16use crate::indexer_reader::IndexerReader;
17
18pub(crate) struct TransactionBuilderApi {
19    inner: IndexerReader,
20}
21
22impl TransactionBuilderApi {
23    #[expect(clippy::new_ret_no_self)]
24    pub fn new(inner: IndexerReader) -> IotaTransactionBuilderApi {
25        IotaTransactionBuilderApi::new_with_data_reader(std::sync::Arc::new(Self { inner }))
26    }
27}
28
29#[async_trait]
30impl DataReader for TransactionBuilderApi {
31    async fn get_owned_objects(
32        &self,
33        address: IotaAddress,
34        object_type: StructTag,
35    ) -> Result<Vec<ObjectInfo>, anyhow::Error> {
36        let stored_objects = self
37            .inner
38            .get_owned_objects_in_blocking_task(
39                address,
40                Some(IotaObjectDataFilter::StructType(object_type)),
41                None,
42                50, // Limit the number of objects returned to 50
43            )
44            .await?;
45
46        stored_objects
47            .into_iter()
48            .map(|object| {
49                let object = Object::try_from(object)?;
50                let object_ref = object.compute_object_reference();
51                let info = ObjectInfo::new(&object_ref, &object);
52                Ok(info)
53            })
54            .collect::<Result<Vec<_>, _>>()
55    }
56
57    async fn get_object_with_options(
58        &self,
59        object_id: ObjectID,
60        options: IotaObjectDataOptions,
61    ) -> Result<IotaObjectResponse, anyhow::Error> {
62        let result = self
63            .inner
64            .get_object_read_in_blocking_task(object_id)
65            .await?;
66        Ok((result, options).try_into()?)
67    }
68
69    async fn get_reference_gas_price(&self) -> Result<u64, anyhow::Error> {
70        let epoch_info = GovernanceReadApi::new(self.inner.clone())
71            .get_epoch_info(None)
72            .await?;
73        Ok(epoch_info
74            .reference_gas_price
75            .ok_or_else(|| anyhow::anyhow!("missing latest reference_gas_price"))?)
76    }
77}