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