drift_rs/grpc/mod.rs
1//! Drift gRPC module
2
3use solana_sdk::{
4 clock::{Epoch, Slot},
5 pubkey::Pubkey,
6};
7pub mod grpc_subscriber;
8use grpc_subscriber::{AccountFilter, GrpcConnectionOpts};
9
10/// grpc account update callback
11pub type OnAccountFn = dyn Fn(&AccountUpdate) + Send + Sync + 'static;
12/// grpc slot update callback
13pub type OnSlotFn = dyn Fn(Slot) + Send + Sync + 'static;
14
15/// Account update from gRPC
16#[derive(PartialEq, Eq, Clone)]
17pub struct AccountUpdate<'a> {
18 /// the account's pubkey
19 pub pubkey: Pubkey,
20 /// lamports in the account
21 pub lamports: u64,
22 /// data held in the account
23 pub data: &'a [u8],
24 /// the program that owns the account. If executable, the program that loads the account.
25 pub owner: Pubkey,
26 /// the account's data contains a loaded program (and is now read-only)
27 pub executable: bool,
28 /// the epoch at which the account will next owe rent
29 pub rent_epoch: Epoch,
30 /// Slot the update was retrieved
31 pub slot: Slot,
32}
33
34/// Config options for drift gRPC subscription
35///
36/// ```example(no_run)
37/// // subscribe to all user and users stats accounts
38/// let opts = GrpcSubscribeOpts::default()
39/// .usermap_on() // subscribe to ALL user accounts
40/// .statsmap_on(); // subscribe to ALL user stats accounts
41///
42/// // cache specific user accounts only and set a new slot callback
43/// let first_3_subaccounts = (0_u16..3).into_iter().map(|i| wallet.sub_account(i)).collect();
44/// let opts = GrpcSubscribeOpts::default()
45/// .user_accounts(first_3_subaccounts);
46/// .on_slot(move |new_slot| {}) // slot callback
47/// ```
48///
49#[derive(Default)]
50pub struct GrpcSubscribeOpts {
51 /// toggle usermap
52 pub usermap: bool,
53 /// toggle user stats map
54 pub user_stats_map: bool,
55 /// list of user (sub)accounts to subscribe
56 pub user_accounts: Vec<Pubkey>,
57 /// callback for slot updates
58 pub on_slot: Option<Box<OnSlotFn>>,
59 /// custom callback for account updates
60 pub on_account: Option<(AccountFilter, Box<OnAccountFn>)>,
61 /// Network level connection config
62 pub connection_opts: GrpcConnectionOpts,
63}
64
65impl GrpcSubscribeOpts {
66 /// Cache ALL drift `User` account updates
67 ///
68 /// useful for e.g. building the DLOB, fast TX building for makers
69 ///
70 /// note: memory requirements ~2GiB
71 pub fn usermap_on(mut self) -> Self {
72 self.usermap = true;
73 self
74 }
75 /// Cache ALL drift `UserStats` account updates
76 ///
77 /// useful for e.g. fast TX building for makers
78 pub fn statsmap_on(mut self) -> Self {
79 self.user_stats_map = true;
80 self
81 }
82 /// Cache account updates for given `users` only
83 pub fn user_accounts(mut self, users: Vec<Pubkey>) -> Self {
84 self.user_accounts = users;
85 self
86 }
87 /// Set a callback to invoke on new slot updates
88 ///
89 /// * `on_slot` - the callback for new slot updates
90 ///
91 /// ! `on_slot` must not block the gRPC task
92 pub fn on_slot(mut self, on_slot: impl Fn(Slot) + Send + Sync + 'static) -> Self {
93 self.on_slot = Some(Box::new(on_slot));
94 self
95 }
96 /// Register a custom callback for account updates
97 ///
98 /// * `filter` - accounts matching filter will invoke the callback
99 /// * `on_account` - fn to invoke on matching account update
100 ///
101 /// ! `on_account` must not block the gRPC task
102 pub fn on_account(
103 mut self,
104 filter: AccountFilter,
105 on_account: impl Fn(&AccountUpdate) + Send + Sync + 'static,
106 ) -> Self {
107 self.on_account = Some((filter, Box::new(on_account)));
108 self
109 }
110 /// Set network level connection opts
111 pub fn connection_opts(mut self, opts: GrpcConnectionOpts) -> Self {
112 self.connection_opts = opts;
113 self
114 }
115}