1use anchor_lang::{
2 prelude::borsh::BorshSchema,
3 prelude::Pubkey,
4 prelude::*,
5 solana_program::{instruction::Instruction, pubkey as key},
6 AnchorDeserialize,
7};
8use sablier_macros::MinSpace;
9use serde::{Deserialize, Serialize};
10use std::{convert::TryFrom, fmt::Debug, hash::Hash};
11
12use crate::pyth::FeedId;
13
14pub const PAYER_PUBKEY: Pubkey = key!("Sab1ierPayer1111111111111111111111111111111");
16
17extern crate self as sablier_utils;
18
19#[derive(AnchorDeserialize, AnchorSerialize, MinSpace, BorshSchema, Clone, Debug, PartialEq)]
21pub struct ClockData {
22 pub slot: u64,
24 pub epoch: u64,
26 pub unix_timestamp: i64,
28}
29
30impl From<Clock> for ClockData {
31 fn from(clock: Clock) -> Self {
32 ClockData {
33 slot: clock.slot,
34 epoch: clock.epoch,
35 unix_timestamp: clock.unix_timestamp,
36 }
37 }
38}
39
40impl TryFrom<Vec<u8>> for ClockData {
41 type Error = Error;
42 fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
43 Ok(
44 borsh::try_from_slice_with_schema::<ClockData>(data.as_slice())
45 .map_err(|_err| ErrorCode::AccountDidNotDeserialize)?,
46 )
47 }
48}
49
50#[derive(AnchorDeserialize, AnchorSerialize, MinSpace, Debug, Clone, PartialEq)]
52pub enum Trigger {
53 Account {
55 address: Pubkey,
57 offset: u64,
59 size: u64,
61 },
62
63 Cron {
65 #[max_len(32)]
67 schedule: String,
68
69 skippable: bool,
72 },
73
74 Now,
76
77 Slot { slot: u64 },
79
80 Epoch { epoch: u64 },
82
83 Timestamp { unix_ts: i64 },
85
86 Pyth {
88 #[raw_space(32)]
90 feed_id: FeedId, equality: Equality,
93 limit: i64,
95 },
96
97 Periodic { delay: u64 },
99}
100
101#[repr(u8)]
103#[derive(AnchorDeserialize, AnchorSerialize, MinSpace, Clone, Debug, Eq, PartialEq, Hash)]
104pub enum Equality {
105 GreaterThanOrEqual,
106 LessThanOrEqual,
107}
108
109#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug, Default)]
111pub struct ThreadResponse {
112 pub close_to: Option<Pubkey>,
115 pub dynamic_instruction: Option<SerializableInstruction>,
118 pub trigger: Option<Trigger>,
120}
121
122#[derive(
124 AnchorDeserialize,
125 AnchorSerialize,
126 Serialize,
127 Deserialize,
128 BorshSchema,
129 Clone,
130 Debug,
131 Hash,
132 PartialEq,
133)]
134pub struct SerializableInstruction {
135 pub program_id: Pubkey,
137 pub accounts: Vec<SerializableAccount>,
139 pub data: Vec<u8>,
141}
142
143impl From<Instruction> for SerializableInstruction {
144 fn from(instruction: Instruction) -> Self {
145 SerializableInstruction {
146 program_id: instruction.program_id,
147 accounts: instruction
148 .accounts
149 .iter()
150 .map(|a| SerializableAccount {
151 pubkey: a.pubkey,
152 is_signer: a.is_signer,
153 is_writable: a.is_writable,
154 })
155 .collect(),
156 data: instruction.data,
157 }
158 }
159}
160
161impl From<&SerializableInstruction> for Instruction {
162 fn from(instruction: &SerializableInstruction) -> Self {
163 Instruction {
164 program_id: instruction.program_id,
165 accounts: instruction
166 .accounts
167 .iter()
168 .map(|a| AccountMeta {
169 pubkey: a.pubkey,
170 is_signer: a.is_signer,
171 is_writable: a.is_writable,
172 })
173 .collect(),
174 data: instruction.data.clone(),
175 }
176 }
177}
178
179impl TryFrom<Vec<u8>> for SerializableInstruction {
180 type Error = Error;
181 fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
182 Ok(
183 borsh::try_from_slice_with_schema::<SerializableInstruction>(data.as_slice())
184 .map_err(|_err| ErrorCode::AccountDidNotDeserialize)?,
185 )
186 }
187}
188
189#[derive(
191 AnchorDeserialize,
192 AnchorSerialize,
193 Serialize,
194 Deserialize,
195 BorshSchema,
196 Clone,
197 Debug,
198 Hash,
199 PartialEq,
200)]
201pub struct SerializableAccount {
202 pub pubkey: Pubkey,
204 pub is_signer: bool,
206 pub is_writable: bool,
208}
209
210impl SerializableAccount {
211 pub fn mutable(pubkey: Pubkey, signer: bool) -> Self {
213 Self {
214 pubkey,
215 is_signer: signer,
216 is_writable: true,
217 }
218 }
219
220 pub fn readonly(pubkey: Pubkey, signer: bool) -> Self {
222 Self {
223 pubkey,
224 is_signer: signer,
225 is_writable: false,
226 }
227 }
228}