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