1use async_trait::async_trait;
7use iota_interaction::OptionalSync;
8use iota_interaction::rpc_types::{IotaTransactionBlockEffects, IotaTransactionBlockEvents};
9use iota_interaction::types::base_types::{IotaAddress, ObjectID};
10use iota_interaction::types::transaction::ProgrammableTransaction;
11use product_common::core_client::CoreClientReadOnly;
12use product_common::transaction::transaction_builder::Transaction;
13use tokio::sync::OnceCell;
14
15use super::operations::TrailOps;
16use crate::core::types::{AuditTrailDeleted, Event};
17use crate::error::Error;
18
19#[derive(Debug, Clone)]
27pub struct Migrate {
28 trail_id: ObjectID,
29 owner: IotaAddress,
30 selected_capability_id: Option<ObjectID>,
31 cached_ptb: OnceCell<ProgrammableTransaction>,
32}
33
34impl Migrate {
35 pub fn new(trail_id: ObjectID, owner: IotaAddress, selected_capability_id: Option<ObjectID>) -> Self {
37 Self {
38 trail_id,
39 owner,
40 selected_capability_id,
41 cached_ptb: OnceCell::new(),
42 }
43 }
44
45 async fn make_ptb<C>(&self, client: &C) -> Result<ProgrammableTransaction, Error>
46 where
47 C: CoreClientReadOnly + OptionalSync,
48 {
49 TrailOps::migrate(client, self.trail_id, self.owner, self.selected_capability_id).await
50 }
51}
52
53#[cfg_attr(not(feature = "send-sync"), async_trait(?Send))]
54#[cfg_attr(feature = "send-sync", async_trait)]
55impl Transaction for Migrate {
56 type Error = Error;
57 type Output = ();
58
59 async fn build_programmable_transaction<C>(&self, client: &C) -> Result<ProgrammableTransaction, Self::Error>
60 where
61 C: CoreClientReadOnly + OptionalSync,
62 {
63 self.cached_ptb.get_or_try_init(|| self.make_ptb(client)).await.cloned()
64 }
65
66 async fn apply<C>(self, _: &mut IotaTransactionBlockEffects, _: &C) -> Result<Self::Output, Self::Error>
67 where
68 C: CoreClientReadOnly + OptionalSync,
69 {
70 Ok(())
71 }
72}
73
74#[derive(Debug, Clone)]
81pub struct UpdateMetadata {
82 trail_id: ObjectID,
83 owner: IotaAddress,
84 metadata: Option<String>,
85 selected_capability_id: Option<ObjectID>,
86 cached_ptb: OnceCell<ProgrammableTransaction>,
87}
88
89impl UpdateMetadata {
90 pub fn new(
92 trail_id: ObjectID,
93 owner: IotaAddress,
94 metadata: Option<String>,
95 selected_capability_id: Option<ObjectID>,
96 ) -> Self {
97 Self {
98 trail_id,
99 owner,
100 metadata,
101 selected_capability_id,
102 cached_ptb: OnceCell::new(),
103 }
104 }
105
106 async fn make_ptb<C>(&self, client: &C) -> Result<ProgrammableTransaction, Error>
107 where
108 C: CoreClientReadOnly + OptionalSync,
109 {
110 TrailOps::update_metadata(
111 client,
112 self.trail_id,
113 self.owner,
114 self.metadata.clone(),
115 self.selected_capability_id,
116 )
117 .await
118 }
119}
120
121#[cfg_attr(not(feature = "send-sync"), async_trait(?Send))]
122#[cfg_attr(feature = "send-sync", async_trait)]
123impl Transaction for UpdateMetadata {
124 type Error = Error;
125 type Output = ();
126
127 async fn build_programmable_transaction<C>(&self, client: &C) -> Result<ProgrammableTransaction, Self::Error>
128 where
129 C: CoreClientReadOnly + OptionalSync,
130 {
131 self.cached_ptb.get_or_try_init(|| self.make_ptb(client)).await.cloned()
132 }
133
134 async fn apply<C>(self, _: &mut IotaTransactionBlockEffects, _: &C) -> Result<Self::Output, Self::Error>
135 where
136 C: CoreClientReadOnly + OptionalSync,
137 {
138 Ok(())
139 }
140}
141
142#[derive(Debug, Clone)]
150pub struct DeleteAuditTrail {
151 trail_id: ObjectID,
152 owner: IotaAddress,
153 selected_capability_id: Option<ObjectID>,
154 cached_ptb: OnceCell<ProgrammableTransaction>,
155}
156
157impl DeleteAuditTrail {
158 pub fn new(trail_id: ObjectID, owner: IotaAddress, selected_capability_id: Option<ObjectID>) -> Self {
160 Self {
161 trail_id,
162 owner,
163 selected_capability_id,
164 cached_ptb: OnceCell::new(),
165 }
166 }
167
168 async fn make_ptb<C>(&self, client: &C) -> Result<ProgrammableTransaction, Error>
169 where
170 C: CoreClientReadOnly + OptionalSync,
171 {
172 TrailOps::delete_audit_trail(client, self.trail_id, self.owner, self.selected_capability_id).await
173 }
174}
175
176#[cfg_attr(not(feature = "send-sync"), async_trait(?Send))]
177#[cfg_attr(feature = "send-sync", async_trait)]
178impl Transaction for DeleteAuditTrail {
179 type Error = Error;
180 type Output = AuditTrailDeleted;
181
182 async fn build_programmable_transaction<C>(&self, client: &C) -> Result<ProgrammableTransaction, Self::Error>
183 where
184 C: CoreClientReadOnly + OptionalSync,
185 {
186 self.cached_ptb.get_or_try_init(|| self.make_ptb(client)).await.cloned()
187 }
188
189 async fn apply_with_events<C>(
190 self,
191 _: &mut IotaTransactionBlockEffects,
192 events: &mut IotaTransactionBlockEvents,
193 _: &C,
194 ) -> Result<Self::Output, Self::Error>
195 where
196 C: CoreClientReadOnly + OptionalSync,
197 {
198 let event = events
199 .data
200 .iter()
201 .find_map(|data| serde_json::from_value::<Event<AuditTrailDeleted>>(data.parsed_json.clone()).ok())
202 .ok_or_else(|| Error::UnexpectedApiResponse("Expected AuditTrailDeleted event not found".to_string()))?;
203
204 Ok(event.data)
205 }
206
207 async fn apply<C>(self, _: &mut IotaTransactionBlockEffects, _: &C) -> Result<Self::Output, Self::Error>
208 where
209 C: CoreClientReadOnly + OptionalSync,
210 {
211 unreachable!()
212 }
213}