@@ -90,16 +90,16 @@ pub struct AppState {
9090 pub client : Arc < DriftClient > ,
9191 /// Solana tx commitment level for preflight confirmation
9292 tx_commitment : CommitmentConfig ,
93- /// default sub_account_id to use if not provided
94- default_subaccount_id : u16 ,
93+ /// sub_account_ids to subscribe to
94+ sub_account_ids : Vec < u16 > ,
9595 /// skip tx preflight on send or not (default: false)
9696 skip_tx_preflight : bool ,
9797 priority_fee_subscriber : Arc < PriorityFeeSubscriber > ,
9898 slot_subscriber : Arc < SlotSubscriber > ,
9999 /// list of additional RPC endpoints for tx broadcast
100100 extra_rpcs : Vec < Arc < RpcClient > > ,
101101 /// swift node url
102- swift_node : Option < String > ,
102+ swift_node : String ,
103103}
104104
105105impl AppState {
@@ -111,12 +111,12 @@ impl AppState {
111111 pub fn signer ( & self ) -> Pubkey {
112112 self . wallet . signer ( )
113113 }
114- pub fn default_sub_account ( & self ) -> Pubkey {
115- self . wallet . sub_account ( self . default_subaccount_id )
114+ pub fn sub_account ( & self , sub_account_id : u16 ) -> Pubkey {
115+ self . wallet . sub_account ( sub_account_id )
116116 }
117117 pub fn resolve_sub_account ( & self , sub_account_id : Option < u16 > ) -> Pubkey {
118118 self . wallet
119- . sub_account ( sub_account_id. unwrap_or ( self . default_subaccount_id ) )
119+ . sub_account ( sub_account_id. unwrap_or ( self . default_sub_account_id ( ) ) )
120120 }
121121
122122 /// Initialize Gateway Drift client
@@ -125,18 +125,18 @@ impl AppState {
125125 /// * `devnet` - whether to run against devnet or not
126126 /// * `wallet` - wallet to use for tx signing
127127 /// * `commitment` - Slot finalisation/commitement levels
128- /// * `default_subaccount_id ` - by default all queries will use this sub-account
128+ /// * `sub_account_ids ` - the sub_accounts to subscribe too. In your query specify a specific subaccount, otherwise subaccount 0 will be used as default
129129 /// * `skip_tx_preflight` - submit txs without checking preflight results
130130 /// * `extra_rpcs` - list of additional RPC endpoints for tx submission
131131 pub async fn new (
132132 endpoint : & str ,
133133 devnet : bool ,
134134 wallet : Wallet ,
135135 commitment : Option < ( CommitmentConfig , CommitmentConfig ) > ,
136- default_subaccount_id : Option < u16 > ,
136+ sub_account_ids : Vec < u16 > ,
137137 skip_tx_preflight : bool ,
138138 extra_rpcs : Vec < & str > ,
139- swift_node : Option < String > ,
139+ swift_node : String ,
140140 ) -> Self {
141141 let ( state_commitment, tx_commitment) =
142142 commitment. unwrap_or ( ( CommitmentConfig :: confirmed ( ) , CommitmentConfig :: confirmed ( ) ) ) ;
@@ -151,11 +151,13 @@ impl AppState {
151151 . await
152152 . expect ( "ok" ) ;
153153
154- let default_subaccount = wallet. sub_account ( default_subaccount_id. unwrap_or ( 0 ) ) ;
155- if let Err ( err) = client. subscribe_account ( & default_subaccount) . await {
156- log:: error!( target: LOG_TARGET , "couldn't subscribe to user updates: {err:?}" ) ;
157- } else {
158- log:: info!( target: LOG_TARGET , "subscribed to subaccount: {default_subaccount}" ) ;
154+ for sub_account_id in & sub_account_ids {
155+ let sub_account = wallet. sub_account ( * sub_account_id) ;
156+ if let Err ( err) = client. subscribe_account ( & sub_account) . await {
157+ log:: error!( target: LOG_TARGET , "couldn't subscribe to user updates: {err:?}. subaccount: {sub_account_id}" ) ;
158+ } else {
159+ log:: info!( target: LOG_TARGET , "subscribed to subaccount: {sub_account}" ) ;
160+ }
159161 }
160162
161163 let priority_fee_subscriber = PriorityFeeSubscriber :: with_config (
@@ -190,7 +192,7 @@ impl AppState {
190192 Self {
191193 client : Arc :: new ( client) ,
192194 tx_commitment,
193- default_subaccount_id : default_subaccount_id . unwrap_or ( 0 ) ,
195+ sub_account_ids ,
194196 skip_tx_preflight,
195197 priority_fee_subscriber,
196198 slot_subscriber : Arc :: new ( slot_subscriber) ,
@@ -207,11 +209,26 @@ impl AppState {
207209 & self ,
208210 configured_markets : & [ MarketId ] ,
209211 ) -> Result < ( ) , SdkError > {
210- let default_sub_account = self . default_sub_account ( ) ;
212+ let sub_account_ids = self . sub_account_ids . clone ( ) ;
213+ for id in sub_account_ids {
214+ self . sync_market_subscriptions_on_user_subaccount_changes ( configured_markets, id)
215+ . await ?;
216+ }
217+
218+ Ok ( ( ) )
219+ }
220+
221+ async fn sync_market_subscriptions_on_user_subaccount_changes (
222+ & self ,
223+ configured_markets : & [ MarketId ] ,
224+ sub_account_id : u16 ,
225+ ) -> Result < ( ) , SdkError > {
226+ let sub_account = self . sub_account ( sub_account_id) ;
211227 let state_commitment = self . tx_commitment ;
212228 let configured_markets_vec = configured_markets. to_vec ( ) ;
213229 let self_clone = self . clone ( ) ;
214- let mut current_user_markets_to_subscribe = self . get_marketids_to_subscribe ( ) . await ?;
230+ let mut current_user_markets_to_subscribe =
231+ self . get_marketids_to_subscribe ( sub_account) . await ?;
215232
216233 tokio:: spawn ( async move {
217234 let pubsub_config = RpcAccountInfoConfig {
@@ -224,7 +241,7 @@ impl AppState {
224241 let pubsub_client = self_clone. client . ws ( ) ;
225242
226243 let ( mut account_subscription, unsubscribe_fn) = match pubsub_client
227- . account_subscribe ( & default_sub_account , Some ( pubsub_config) )
244+ . account_subscribe ( & sub_account , Some ( pubsub_config) )
228245 . await
229246 {
230247 Ok ( res) => res,
@@ -239,7 +256,7 @@ impl AppState {
239256 // Process incoming account updates
240257 while let Some ( _) = account_subscription. next ( ) . await {
241258 let current_market_ids_count = current_user_markets_to_subscribe. len ( ) ;
242- match self_clone. get_marketids_to_subscribe ( ) . await {
259+ match self_clone. get_marketids_to_subscribe ( sub_account ) . await {
243260 Ok ( new_market_ids) => {
244261 if new_market_ids. len ( ) != current_market_ids_count {
245262 if let Err ( err) = self_clone
@@ -267,13 +284,13 @@ impl AppState {
267284 Ok ( ( ) )
268285 }
269286
270- async fn get_marketids_to_subscribe ( & self ) -> Result < Vec < MarketId > , SdkError > {
271- let ( all_spot , all_perp ) = self
272- . client
273- . all_positions ( & self . default_sub_account ( ) )
274- . await ?;
287+ async fn get_marketids_to_subscribe (
288+ & self ,
289+ sub_account : Pubkey ,
290+ ) -> Result < Vec < MarketId > , SdkError > {
291+ let ( all_spot , all_perp ) = self . client . all_positions ( & sub_account ) . await ?;
275292
276- let open_orders = self . client . all_orders ( & self . default_sub_account ( ) ) . await ?;
293+ let open_orders = self . client . all_orders ( & sub_account ) . await ?;
277294
278295 let user_markets: Vec < MarketId > = all_spot
279296 . iter ( )
@@ -296,11 +313,25 @@ impl AppState {
296313 /// * configured_markets - list of static markets provided by user
297314 ///
298315 /// additional subscriptions will be included based on user's current positions (on default sub-account)
316+
299317 pub ( crate ) async fn subscribe_market_data (
300318 & self ,
301319 configured_markets : & [ MarketId ] ,
302320 ) -> Result < ( ) , SdkError > {
303- let mut user_markets = self . get_marketids_to_subscribe ( ) . await ?;
321+ for id in self . sub_account_ids . clone ( ) {
322+ self . subscribe_market_data_for_subaccount ( configured_markets, id)
323+ . await ?;
324+ }
325+ Ok ( ( ) )
326+ }
327+
328+ async fn subscribe_market_data_for_subaccount (
329+ & self ,
330+ configured_markets : & [ MarketId ] ,
331+ sub_account_id : u16 ,
332+ ) -> Result < ( ) , SdkError > {
333+ let sub_account = self . sub_account ( sub_account_id) ;
334+ let mut user_markets = self . get_marketids_to_subscribe ( sub_account) . await ?;
304335 user_markets. extend_from_slice ( configured_markets) ;
305336
306337 let init_rpc_throttle: u64 = std:: env:: var ( "INIT_RPC_THROTTLE" )
@@ -636,7 +667,7 @@ impl AppState {
636667 let orders_len = orders_iter. len ( ) ;
637668 let mut signed_messages = Vec :: with_capacity ( orders_len) ;
638669 let mut hashes: Vec < String > = Vec :: with_capacity ( orders_len) ;
639- let sub_account_id = ctx. sub_account_id . unwrap_or ( self . default_subaccount_id ) ;
670+ let sub_account_id = ctx. sub_account_id . unwrap_or ( self . default_sub_account_id ( ) ) ;
640671 let current_slot = self . slot_subscriber . current_slot ( ) ;
641672 let orders_with_hex: Vec < ( OrderParams , Vec < u8 > ) > = orders_iter
642673 . map ( |order| {
@@ -663,7 +694,7 @@ impl AppState {
663694 } ;
664695 let incoming_msg = IncomingSignedMessage {
665696 taker_authority : self . authority ( ) . to_string ( ) ,
666- signature : general_purpose:: STANDARD . encode ( signature) ,
697+ signature : general_purpose:: STANDARD . encode ( signature) , // TODO: test just using .to_string() for base64 encoding
667698 message : String :: from_utf8 ( message) . unwrap ( ) ,
668699 signing_authority : self . signer ( ) . to_string ( ) ,
669700 market_type,
@@ -677,11 +708,7 @@ impl AppState {
677708
678709 let client = reqwest:: Client :: new ( ) ;
679710
680- let swift_orders_url = self
681- . swift_node
682- . clone ( )
683- . unwrap_or ( "https://master.swift.drift.trade" . to_string ( ) )
684- + "/orders" ;
711+ let swift_orders_url = self . swift_node . clone ( ) + "/orders" ;
685712
686713 let mut futures = FuturesOrdered :: new ( ) ;
687714 for msg in signed_messages {
@@ -900,7 +927,7 @@ impl AppState {
900927 ctx : Context ,
901928 new_margin_ratio : Decimal ,
902929 ) -> GatewayResult < TxResponse > {
903- let sub_account_id = ctx. sub_account_id . unwrap_or ( self . default_subaccount_id ) ;
930+ let sub_account_id = ctx. sub_account_id . unwrap_or ( self . default_sub_account_id ( ) ) ;
904931 let sub_account_address = self . wallet . sub_account ( sub_account_id) ;
905932 let account_data = self . client . get_user_account ( & sub_account_address) . await ?;
906933
@@ -921,6 +948,10 @@ impl AppState {
921948 self . send_tx ( tx, "set_margin_ratio" , ctx. ttl ) . await
922949 }
923950
951+ pub fn default_sub_account_id ( & self ) -> u16 {
952+ self . sub_account_ids [ 0 ]
953+ }
954+
924955 fn get_priority_fee ( & self ) -> u64 {
925956 self . priority_fee_subscriber . priority_fee_nth ( 0.9 )
926957 }
0 commit comments