iota_types/timelock/
timelock.rs1use iota_sdk_types::{StructTag, TypeTag};
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 base_types::ObjectID,
9 error::IotaError,
10 gas_coin::GasCoin,
11 id::UID,
12 object::{Data, Object},
13};
14
15pub const VESTED_REWARD_ID_PREFIX: &str =
18 "0xb191c4bc825ac6983789e50545d5ef07a1d293a98ad974fc9498cb18";
19
20#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
22pub struct TimeLock<T> {
23 id: UID,
24 locked: T,
26 expiration_timestamp_ms: u64,
28 label: Option<String>,
30}
31
32impl<T> TimeLock<T> {
33 pub fn new(id: UID, locked: T, expiration_timestamp_ms: u64, label: Option<String>) -> Self {
35 Self {
36 id,
37 locked,
38 expiration_timestamp_ms,
39 label,
40 }
41 }
42
43 pub fn id(&self) -> &ObjectID {
45 self.id.object_id()
46 }
47
48 pub fn locked(&self) -> &T {
50 &self.locked
51 }
52
53 pub fn expiration_timestamp_ms(&self) -> u64 {
55 self.expiration_timestamp_ms
56 }
57
58 pub fn label(&self) -> &Option<String> {
60 &self.label
61 }
62}
63
64impl<'de, T> TimeLock<T>
65where
66 T: Serialize + Deserialize<'de>,
67{
68 pub fn from_bcs_bytes(content: &'de [u8]) -> Result<Self, IotaError> {
70 bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
71 error: format!("Unable to deserialize TimeLock object: {err:?}"),
72 })
73 }
74
75 pub fn to_bcs_bytes(&self) -> Vec<u8> {
77 bcs::to_bytes(&self).unwrap()
78 }
79}
80
81pub fn is_timelocked_balance(other: &StructTag) -> bool {
83 if !other.is_time_lock() {
84 return false;
85 }
86
87 match &other.type_params()[0] {
88 TypeTag::Struct(tag) => tag.is_balance(),
89 _ => false,
90 }
91}
92
93pub fn is_timelocked_gas_balance(other: &StructTag) -> bool {
95 if !other.is_time_lock() {
96 return false;
97 }
98
99 match &other.type_params()[0] {
100 TypeTag::Struct(tag) => GasCoin::is_gas_balance(tag),
101 _ => false,
102 }
103}
104
105impl<'de, T> TryFrom<&'de Object> for TimeLock<T>
106where
107 T: Serialize + Deserialize<'de>,
108{
109 type Error = IotaError;
110
111 fn try_from(object: &'de Object) -> Result<Self, Self::Error> {
112 match &object.data {
113 Data::Struct(o) => {
114 if o.struct_tag().is_time_lock() {
115 return TimeLock::from_bcs_bytes(o.contents());
116 }
117 }
118 Data::Package(_) => {}
119 }
120
121 Err(IotaError::Type {
122 error: format!("Object type is not a TimeLock: {object:?}"),
123 })
124 }
125}