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