1use std::str::FromStr;
6
7use anyhow::ensure;
8use iota_sdk_types::{Event, TransactionDigest};
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use serde_with::serde_as;
12
13use crate::iota_serde::{BigInt, Readable};
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct EventEnvelope {
18 pub timestamp: u64,
20 pub tx_digest: TransactionDigest,
22 pub event_num: u64,
24 pub event: Event,
26 pub parsed_json: Value,
28}
29#[serde_as]
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
33#[serde(rename_all = "camelCase")]
34pub struct EventID {
35 pub tx_digest: TransactionDigest,
36 #[serde_as(as = "Readable<BigInt<u64>, _>")]
37 pub event_seq: u64,
38}
39
40impl From<(TransactionDigest, u64)> for EventID {
41 fn from((tx_digest_num, event_seq_number): (TransactionDigest, u64)) -> Self {
42 Self {
43 tx_digest: tx_digest_num as TransactionDigest,
44 event_seq: event_seq_number,
45 }
46 }
47}
48
49impl From<EventID> for String {
50 fn from(id: EventID) -> Self {
51 format!("{:?}:{}", id.tx_digest, id.event_seq)
52 }
53}
54
55impl TryFrom<String> for EventID {
56 type Error = anyhow::Error;
57
58 fn try_from(value: String) -> Result<Self, Self::Error> {
59 let values = value.split(':').collect::<Vec<_>>();
60 ensure!(values.len() == 2, "Malformed EventID : {value}");
61 Ok((
62 TransactionDigest::from_str(values[0])?,
63 u64::from_str(values[1])?,
64 )
65 .into())
66 }
67}
68
69impl EventEnvelope {
70 pub fn new(
71 timestamp: u64,
72 tx_digest: TransactionDigest,
73 event_num: u64,
74 event: Event,
75 move_struct_json_value: Value,
76 ) -> Self {
77 Self {
78 timestamp,
79 tx_digest,
80 event_num,
81 event,
82 parsed_json: move_struct_json_value,
83 }
84 }
85}
86
87#[derive(Deserialize)]
88pub enum SystemEpochInfoEvent {
89 V1(SystemEpochInfoEventV1),
90 V2(SystemEpochInfoEventV2),
91}
92
93impl SystemEpochInfoEvent {
94 pub fn supply_change(&self) -> i64 {
95 match self {
96 SystemEpochInfoEvent::V1(event) => {
97 event.minted_tokens_amount as i64 - event.burnt_tokens_amount as i64
98 }
99 SystemEpochInfoEvent::V2(event) => {
100 event.minted_tokens_amount as i64 - event.burnt_tokens_amount as i64
101 }
102 }
103 }
104}
105
106impl From<Event> for SystemEpochInfoEvent {
107 fn from(event: Event) -> Self {
108 if event.is_system_epoch_info_event_v2() {
109 SystemEpochInfoEvent::V2(
110 bcs::from_bytes::<SystemEpochInfoEventV2>(&event.contents)
111 .expect("event deserialization should succeed as type was pre-validated"),
112 )
113 } else {
114 SystemEpochInfoEvent::V1(
115 bcs::from_bytes::<SystemEpochInfoEventV1>(&event.contents)
116 .expect("event deserialization should succeed as type was pre-validated"),
117 )
118 }
119 }
120}
121
122#[derive(Serialize, Deserialize, Default)]
124pub struct SystemEpochInfoEventV1 {
125 pub epoch: u64,
126 pub protocol_version: u64,
127 pub reference_gas_price: u64,
128 pub total_stake: u64,
129 pub storage_charge: u64,
130 pub storage_rebate: u64,
131 pub storage_fund_balance: u64,
132 pub total_gas_fees: u64,
133 pub total_stake_rewards_distributed: u64,
134 pub burnt_tokens_amount: u64,
135 pub minted_tokens_amount: u64,
136}
137
138#[derive(Serialize, Deserialize, Default)]
144pub struct SystemEpochInfoEventV2 {
145 pub epoch: u64,
146 pub protocol_version: u64,
147 pub total_stake: u64,
148 pub storage_charge: u64,
149 pub storage_rebate: u64,
150 pub storage_fund_balance: u64,
151 pub total_gas_fees: u64,
152 pub total_stake_rewards_distributed: u64,
153 pub burnt_tokens_amount: u64,
154 pub minted_tokens_amount: u64,
155 pub tips_amount: u64,
156}