surfpool_types/
types.rs

1use blake3::Hash;
2use chrono::{DateTime, Local};
3use crossbeam_channel::{Receiver, Sender};
4// use litesvm::types::TransactionMetadata;
5use solana_clock::Clock;
6use solana_epoch_info::EpochInfo;
7use solana_message::inner_instruction::InnerInstructionsList;
8use solana_pubkey::Pubkey;
9use solana_signature::Signature;
10use solana_transaction::versioned::VersionedTransaction;
11use solana_transaction_context::TransactionReturnData;
12use solana_transaction_error::TransactionError;
13use txtx_addon_network_svm_types::subgraph::SubgraphRequest;
14
15use std::{collections::HashMap, path::PathBuf};
16use txtx_addon_kit::types::types::Value;
17use uuid::Uuid;
18
19pub const DEFAULT_RPC_URL: &str = "https://api.mainnet-beta.solana.com";
20
21#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
22pub struct TransactionMetadata {
23    pub signature: Signature,
24    pub logs: Vec<String>,
25    pub inner_instructions: InnerInstructionsList,
26    pub compute_units_consumed: u64,
27    pub return_data: TransactionReturnData,
28}
29
30#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
31#[serde(rename_all = "camelCase")]
32pub enum TransactionConfirmationStatus {
33    Processed,
34    Confirmed,
35    Finalized,
36}
37
38#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
39pub enum BlockProductionMode {
40    #[default]
41    Clock,
42    Transaction,
43    Manual,
44}
45
46#[derive(Debug, Clone)]
47pub struct Collection {
48    pub uuid: Uuid,
49    pub name: String,
50    pub entries: Vec<SubgraphDataEntry>,
51}
52
53#[derive(Debug, Clone)]
54pub struct SubgraphDataEntry {
55    // The UUID of the entry
56    pub uuid: Uuid,
57    // A map of field names and their values
58    pub values: HashMap<String, Value>,
59    // The slot that the transaction that created this entry was processed in
60    pub block_height: u64,
61    // The transaction hash that created this entry
62    pub transaction_hash: Hash,
63}
64
65impl SubgraphDataEntry {
66    pub fn new(values: HashMap<String, Value>, block_height: u64, tx_hash: [u8; 32]) -> Self {
67        Self {
68            uuid: Uuid::new_v4(),
69            values,
70            block_height,
71            transaction_hash: Hash::from_bytes(tx_hash),
72        }
73    }
74}
75
76#[derive(Debug)]
77pub enum SubgraphEvent {
78    EndpointReady,
79    InfoLog(DateTime<Local>, String),
80    ErrorLog(DateTime<Local>, String),
81    WarnLog(DateTime<Local>, String),
82    DebugLog(DateTime<Local>, String),
83    Shutdown,
84}
85
86impl SubgraphEvent {
87    pub fn info<S>(msg: S) -> Self
88    where
89        S: Into<String>,
90    {
91        Self::InfoLog(Local::now(), msg.into())
92    }
93
94    pub fn warn<S>(msg: S) -> Self
95    where
96        S: Into<String>,
97    {
98        Self::WarnLog(Local::now(), msg.into())
99    }
100
101    pub fn error<S>(msg: S) -> Self
102    where
103        S: Into<String>,
104    {
105        Self::ErrorLog(Local::now(), msg.into())
106    }
107
108    pub fn debug<S>(msg: S) -> Self
109    where
110        S: Into<String>,
111    {
112        Self::DebugLog(Local::now(), msg.into())
113    }
114}
115
116#[derive(Debug, Clone, Deserialize, Serialize)]
117pub enum SchemaDataSourcingEvent {
118    Rountrip(Uuid),
119    ApplyEntry(Uuid, Vec<u8>, u64, [u8; 32]),
120}
121
122#[derive(Debug, Clone)]
123pub enum SubgraphCommand {
124    CreateSubgraph(Uuid, SubgraphRequest, Sender<String>),
125    ObserveSubgraph(Receiver<SchemaDataSourcingEvent>),
126    Shutdown,
127}
128
129#[derive(Debug)]
130pub enum SimnetEvent {
131    Ready,
132    Connected(String),
133    Aborted(String),
134    Shutdown,
135    ClockUpdate(Clock),
136    EpochInfoUpdate(EpochInfo),
137    BlockHashExpired,
138    InfoLog(DateTime<Local>, String),
139    ErrorLog(DateTime<Local>, String),
140    WarnLog(DateTime<Local>, String),
141    DebugLog(DateTime<Local>, String),
142    PluginLoaded(String),
143    TransactionReceived(DateTime<Local>, VersionedTransaction),
144    TransactionProcessed(
145        DateTime<Local>,
146        TransactionMetadata,
147        Option<TransactionError>,
148    ),
149    AccountUpdate(DateTime<Local>, Pubkey),
150}
151
152impl SimnetEvent {
153    pub fn info<S>(msg: S) -> Self
154    where
155        S: Into<String>,
156    {
157        Self::InfoLog(Local::now(), msg.into())
158    }
159
160    pub fn warn<S>(msg: S) -> Self
161    where
162        S: Into<String>,
163    {
164        Self::WarnLog(Local::now(), msg.into())
165    }
166
167    pub fn error<S>(msg: S) -> Self
168    where
169        S: Into<String>,
170    {
171        Self::ErrorLog(Local::now(), msg.into())
172    }
173
174    pub fn debug<S>(msg: S) -> Self
175    where
176        S: Into<String>,
177    {
178        Self::DebugLog(Local::now(), msg.into())
179    }
180
181    pub fn transaction_processed(meta: TransactionMetadata, err: Option<TransactionError>) -> Self {
182        Self::TransactionProcessed(Local::now(), meta, err)
183    }
184
185    pub fn transaction_received(tx: VersionedTransaction) -> Self {
186        Self::TransactionReceived(Local::now(), tx)
187    }
188
189    pub fn account_update(pubkey: Pubkey) -> Self {
190        Self::AccountUpdate(Local::now(), pubkey)
191    }
192}
193
194#[derive(Debug)]
195pub enum TransactionStatusEvent {
196    Success(TransactionConfirmationStatus),
197    SimulationFailure((TransactionError, TransactionMetadata)),
198    ExecutionFailure((TransactionError, TransactionMetadata)),
199}
200
201#[derive(Debug)]
202pub enum SimnetCommand {
203    SlotForward(Option<Hash>),
204    SlotBackward(Option<Hash>),
205    UpdateClock(ClockCommand),
206    UpdateBlockProductionMode(BlockProductionMode),
207    TransactionReceived(
208        Option<Hash>,
209        VersionedTransaction,
210        Sender<TransactionStatusEvent>,
211        bool,
212    ),
213    Terminate(Option<Hash>),
214}
215
216#[derive(Debug)]
217pub enum ClockCommand {
218    Pause,
219    Resume,
220    Toggle,
221    UpdateSlotInterval(u64),
222}
223
224pub enum ClockEvent {
225    Tick,
226    ExpireBlockHash,
227}
228
229#[derive(Clone, Debug, Default)]
230pub struct SurfpoolConfig {
231    pub simnets: Vec<SimnetConfig>,
232    pub rpc: RpcConfig,
233    pub subgraph: SubgraphConfig,
234    pub plugin_config_path: Vec<PathBuf>,
235}
236
237#[derive(Clone, Debug)]
238pub struct SimnetConfig {
239    pub remote_rpc_url: String,
240    pub slot_time: u64,
241    pub block_production_mode: BlockProductionMode,
242    pub airdrop_addresses: Vec<Pubkey>,
243    pub airdrop_token_amount: u64,
244}
245
246impl Default for SimnetConfig {
247    fn default() -> Self {
248        Self {
249            remote_rpc_url: DEFAULT_RPC_URL.to_string(),
250            slot_time: 0,
251            block_production_mode: BlockProductionMode::Clock,
252            airdrop_addresses: vec![],
253            airdrop_token_amount: 0,
254        }
255    }
256}
257
258#[derive(Clone, Debug, Default)]
259pub struct SubgraphConfig {}
260
261#[derive(Clone, Debug)]
262pub struct RpcConfig {
263    pub bind_host: String,
264    pub bind_port: u16,
265}
266
267impl RpcConfig {
268    pub fn get_socket_address(&self) -> String {
269        format!("{}:{}", self.bind_host, self.bind_port)
270    }
271}
272
273#[derive(Debug, Clone, Deserialize, Serialize)]
274pub struct SubgraphPluginConfig {
275    pub uuid: Uuid,
276    pub ipc_token: String,
277    pub subgraph_request: SubgraphRequest,
278}
279
280impl Default for RpcConfig {
281    fn default() -> Self {
282        Self {
283            bind_host: "127.0.0.1".to_string(),
284            bind_port: 8899,
285        }
286    }
287}
288
289#[derive(Serialize, Deserialize, Clone, Debug)]
290pub struct SvmSimnetInitializationRequest {
291    pub domain: String,
292    pub block_production_mode: BlockProductionMode,
293    pub datasource_rpc_url: String,
294}
295
296#[derive(Serialize, Deserialize, Clone, Debug)]
297pub enum SvmSimnetCommand {
298    Init(SvmSimnetInitializationRequest),
299}
300
301#[derive(Serialize, Deserialize)]
302pub struct CreateNetworkRequest {
303    pub workspace_id: Uuid,
304    pub name: String,
305    pub description: Option<String>,
306    pub datasource_rpc_url: String,
307    pub block_production_mode: BlockProductionMode,
308}
309
310impl CreateNetworkRequest {
311    pub fn new(
312        workspace_id: Uuid,
313        name: String,
314        description: Option<String>,
315        datasource_rpc_url: String,
316        block_production_mode: BlockProductionMode,
317    ) -> Self {
318        Self {
319            workspace_id,
320            name,
321            description,
322            datasource_rpc_url,
323            block_production_mode: block_production_mode,
324        }
325    }
326}
327
328#[derive(Serialize, Deserialize)]
329pub struct CreateNetworkResponse {
330    pub rpc_url: String,
331}