diff --git a/index.html b/index.html index 7c336f82..dfe4232b 100644 --- a/index.html +++ b/index.html @@ -444,7 +444,7 @@

Installation

Key Components

@@ -471,7 +471,7 @@

Example

provider = Provider(connection, wallet) drift_client = DriftClient.from_config(config, provider) -drift_user = User(drift_client) +drift_user = DriftUser(drift_client) # open a 10 SOL long position sig = await drift_client.open_position( diff --git a/search/search_index.json b/search/search_index.json index 8b50245a..e74aae93 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Drift-v2 Python SDK DriftPy is the Python SDK for Drift-v2 on Solana. It allows you to trade and fetch data from Drift using Python. Installation pip install driftpy Note: requires Python >= 3.10. Key Components DriftClient / drift_client.py : Used to interact with the protocol (deposit, withdraw, trade, lp, etc.) User / drift_user.py : Used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) accounts.py : Used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) addresses.py : Used to derive on-chain addresses of the accounts (publickey of the sol-market) Example from solana.keypair import Keypair from driftpy.drift_client import DriftClient from driftpy.drift_user import User from driftpy.constants.numeric_constants import BASE_PRECISION , AMM_RESERVE_PRECISION from anchorpy import Provider , Wallet from solana.rpc.async_api import AsyncClient # load keypair from file KEYPATH = '../your-keypair-secret.json' with open ( KEYPATH , 'r' ) as f : secret = json . load ( f ) kp = Keypair . from_secret_key ( bytes ( secret )) # create clearing house for mainnet ENV = 'mainnet' config = configs [ ENV ] wallet = Wallet ( kp ) connection = AsyncClient ( config . default_http ) provider = Provider ( connection , wallet ) drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # clearing house user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Drift-v2 Python SDK"},{"location":"#drift-v2-python-sdk","text":"DriftPy is the Python SDK for Drift-v2 on Solana. It allows you to trade and fetch data from Drift using Python.","title":"Drift-v2 Python SDK"},{"location":"#installation","text":"pip install driftpy Note: requires Python >= 3.10.","title":"Installation"},{"location":"#key-components","text":"DriftClient / drift_client.py : Used to interact with the protocol (deposit, withdraw, trade, lp, etc.) User / drift_user.py : Used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) accounts.py : Used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) addresses.py : Used to derive on-chain addresses of the accounts (publickey of the sol-market)","title":"Key Components"},{"location":"#example","text":"from solana.keypair import Keypair from driftpy.drift_client import DriftClient from driftpy.drift_user import User from driftpy.constants.numeric_constants import BASE_PRECISION , AMM_RESERVE_PRECISION from anchorpy import Provider , Wallet from solana.rpc.async_api import AsyncClient # load keypair from file KEYPATH = '../your-keypair-secret.json' with open ( KEYPATH , 'r' ) as f : secret = json . load ( f ) kp = Keypair . from_secret_key ( bytes ( secret )) # create clearing house for mainnet ENV = 'mainnet' config = configs [ ENV ] wallet = Wallet ( kp ) connection = AsyncClient ( config . default_http ) provider = Provider ( connection , wallet ) drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # clearing house user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Example"},{"location":"accounts/","text":"Accounts These functions are used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) Example drift_client = DriftClient . from_config ( config , provider ) # get sol market info sol_market_index = 0 sol_market = await get_perp_market_account ( drift_client . program , sol_market_index ) print ( sol_market . amm . sqrt_k , sol_market . amm . base_asset_amount_long , sol_market . amm . base_asset_amount_short , ) # get usdc spot market info usdc_spot_market_index = 0 usdc_market = await get_spot_market_account ( drift_client . program , usdc_spot_market_index ) print ( usdc . market_index , usdc . deposit_balance , usdc . borrow_balance , ) accounts special cache special drift_client CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ) Source code in driftpy/accounts/cache/drift_client.py class CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ): def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] async def cache_if_needed ( self ): if self . cache is None : await self . update_cache () __init__ ( self , program , commitment = 'confirmed' ) special Source code in driftpy/accounts/cache/drift_client.py def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None cache_if_needed ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def cache_if_needed ( self ): if self . cache is None : await self . update_cache () get_oracle_data_and_slot ( self , oracle ) async Source code in driftpy/accounts/cache/drift_client.py async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] get_perp_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/cache/drift_client.py async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] get_spot_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/cache/drift_client.py async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] get_state_account_and_slot ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] update_cache ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data user CachedUserAccountSubscriber ( UserAccountSubscriber ) Source code in driftpy/accounts/cache/user.py class CachedUserAccountSubscriber ( UserAccountSubscriber ): def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache () __init__ ( self , user_pubkey , program , commitment = 'confirmed' ) special Source code in driftpy/accounts/cache/user.py def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None cache_if_needed ( self ) async Source code in driftpy/accounts/cache/user.py async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache () get_user_account_and_slot ( self ) async Source code in driftpy/accounts/cache/user.py async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot update_cache ( self ) async Source code in driftpy/accounts/cache/user.py async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot get_accounts get_account_data_and_slot ( address , program , commitment = 'processed' ) async Source code in driftpy/accounts/get_accounts.py async def get_account_data_and_slot ( address : Pubkey , program : Program , commitment : Commitment = \"processed\" ) -> Optional [ DataAndSlot [ T ]]: account_info = await program . provider . connection . get_account_info ( address , encoding = \"base64\" , commitment = commitment , ) if not account_info . value : return None slot = account_info . context . slot data = account_info . value . data decoded_data = program . coder . accounts . decode ( data ) return DataAndSlot ( slot , decoded_data ) get_all_perp_market_accounts ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_all_perp_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"PerpMarket\" ] . all () get_all_spot_market_accounts ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_all_spot_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"SpotMarket\" ] . all () get_if_stake_account ( program , authority , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_if_stake_account ( program : Program , authority : Pubkey , spot_market_index : int ) -> InsuranceFundStake : if_stake_pk = get_insurance_fund_stake_public_key ( program . program_id , authority , spot_market_index ) response = await program . account [ \"InsuranceFundStake\" ] . fetch ( if_stake_pk ) return cast ( InsuranceFundStake , response ) get_perp_market_account ( program , market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account ( program : Program , market_index : int ) -> PerpMarket : return ( await get_perp_market_account_and_slot ( program , market_index )) . data get_perp_market_account_and_slot ( program , market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account_and_slot ( program : Program , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: perp_market_public_key = get_perp_market_public_key ( program . program_id , market_index ) return await get_account_data_and_slot ( perp_market_public_key , program ) get_spot_market_account ( program , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account ( program : Program , spot_market_index : int ) -> SpotMarket : return ( await get_spot_market_account_and_slot ( program , spot_market_index )) . data get_spot_market_account_and_slot ( program , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account_and_slot ( program : Program , spot_market_index : int ) -> DataAndSlot [ SpotMarket ]: spot_market_public_key = get_spot_market_public_key ( program . program_id , spot_market_index ) return await get_account_data_and_slot ( spot_market_public_key , program ) get_state_account ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_state_account ( program : Program ) -> State : return ( await get_state_account_and_slot ( program )) . data get_state_account_and_slot ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_state_account_and_slot ( program : Program ) -> DataAndSlot [ State ]: state_public_key = get_state_public_key ( program . program_id ) return await get_account_data_and_slot ( state_public_key , program ) get_user_account ( program , user_public_key ) async Source code in driftpy/accounts/get_accounts.py async def get_user_account ( program : Program , user_public_key : Pubkey , ) -> User : return ( await get_user_account_and_slot ( program , user_public_key )) . data get_user_account_and_slot ( program , user_public_key ) async Source code in driftpy/accounts/get_accounts.py async def get_user_account_and_slot ( program : Program , user_public_key : Pubkey , ) -> DataAndSlot [ User ]: return await get_account_data_and_slot ( user_public_key , program ) get_user_stats_account ( program , authority ) async Source code in driftpy/accounts/get_accounts.py async def get_user_stats_account ( program : Program , authority : Pubkey , ) -> UserStats : user_stats_public_key = get_user_stats_account_public_key ( program . program_id , authority , ) response = await program . account [ \"UserStats\" ] . fetch ( user_stats_public_key ) return cast ( UserStats , response ) oracle convert_pyth_price ( price , scale = 1 ) Source code in driftpy/accounts/oracle.py def convert_pyth_price ( price , scale = 1 ): return int ( price * PRICE_PRECISION * scale ) get_oracle_price_data_and_slot ( connection , address , oracle_source = OracleSource . PYTH ()) async Source code in driftpy/accounts/oracle.py async def get_oracle_price_data_and_slot ( connection : AsyncClient , address : Pubkey , oracle_source = OracleSource . PYTH () ) -> DataAndSlot [ OraclePriceData ]: if \"Pyth\" in str ( oracle_source ): rpc_reponse = await connection . get_account_info ( address ) rpc_response_slot = rpc_reponse . context . slot ( pyth_price_info , last_slot , twac , twap ) = await _parse_pyth_price_info ( rpc_reponse ) scale = 1 if \"1K\" in str ( oracle_source ): scale = 1e3 elif \"1M\" in str ( oracle_source ): scale = 1e6 oracle_data = OraclePriceData ( price = convert_pyth_price ( pyth_price_info . price , scale ), slot = pyth_price_info . pub_slot , confidence = convert_pyth_price ( pyth_price_info . confidence_interval , scale ), twap = convert_pyth_price ( twap , scale ), twap_confidence = convert_pyth_price ( twac , scale ), has_sufficient_number_of_datapoints = True , ) return DataAndSlot ( data = oracle_data , slot = rpc_response_slot ) elif \"Quote\" in str ( oracle_source ): return DataAndSlot ( data = OraclePriceData ( PRICE_PRECISION , 0 , 1 , 1 , 0 , True ), slot = 0 ) else : raise NotImplementedError ( \"Unsupported Oracle Source\" , str ( oracle_source )) types DataAndSlot ( Generic ) dataclass DataAndSlot(slot: int, data: ~T) Source code in driftpy/accounts/types.py @dataclass class DataAndSlot ( Generic [ T ]): slot : int data : T data : ~ T dataclass-field slot : int dataclass-field __init__ ( self , slot , data ) special DriftClientAccountSubscriber Source code in driftpy/accounts/types.py class DriftClientAccountSubscriber : @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass get_oracle_data_and_slot ( self , oracle ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass get_perp_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass get_spot_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass get_state_account_and_slot ( self ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass UserAccountSubscriber Source code in driftpy/accounts/types.py class UserAccountSubscriber : @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass get_user_account_and_slot ( self ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"Accounts"},{"location":"accounts/#accounts","text":"These functions are used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.)","title":"Accounts"},{"location":"accounts/#example","text":"drift_client = DriftClient . from_config ( config , provider ) # get sol market info sol_market_index = 0 sol_market = await get_perp_market_account ( drift_client . program , sol_market_index ) print ( sol_market . amm . sqrt_k , sol_market . amm . base_asset_amount_long , sol_market . amm . base_asset_amount_short , ) # get usdc spot market info usdc_spot_market_index = 0 usdc_market = await get_spot_market_account ( drift_client . program , usdc_spot_market_index ) print ( usdc . market_index , usdc . deposit_balance , usdc . borrow_balance , )","title":"Example"},{"location":"accounts/#driftpy.accounts","text":"","title":"accounts"},{"location":"accounts/#driftpy.accounts.cache","text":"","title":"cache"},{"location":"accounts/#driftpy.accounts.cache.drift_client","text":"","title":"drift_client"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber","text":"Source code in driftpy/accounts/cache/drift_client.py class CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ): def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] async def cache_if_needed ( self ): if self . cache is None : await self . update_cache ()","title":"CachedDriftClientAccountSubscriber"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.__init__","text":"Source code in driftpy/accounts/cache/drift_client.py def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None","title":"__init__()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.cache_if_needed","text":"Source code in driftpy/accounts/cache/drift_client.py async def cache_if_needed ( self ): if self . cache is None : await self . update_cache ()","title":"cache_if_needed()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_oracle_data_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )]","title":"get_oracle_data_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_perp_market_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ]","title":"get_perp_market_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_spot_market_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ]","title":"get_spot_market_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_state_account_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ]","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.update_cache","text":"Source code in driftpy/accounts/cache/drift_client.py async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data","title":"update_cache()"},{"location":"accounts/#driftpy.accounts.cache.user","text":"","title":"user"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber","text":"Source code in driftpy/accounts/cache/user.py class CachedUserAccountSubscriber ( UserAccountSubscriber ): def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache ()","title":"CachedUserAccountSubscriber"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.__init__","text":"Source code in driftpy/accounts/cache/user.py def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None","title":"__init__()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.cache_if_needed","text":"Source code in driftpy/accounts/cache/user.py async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache ()","title":"cache_if_needed()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.get_user_account_and_slot","text":"Source code in driftpy/accounts/cache/user.py async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot","title":"get_user_account_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.update_cache","text":"Source code in driftpy/accounts/cache/user.py async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot","title":"update_cache()"},{"location":"accounts/#driftpy.accounts.get_accounts","text":"","title":"get_accounts"},{"location":"accounts/#driftpy.accounts.get_accounts.get_account_data_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_account_data_and_slot ( address : Pubkey , program : Program , commitment : Commitment = \"processed\" ) -> Optional [ DataAndSlot [ T ]]: account_info = await program . provider . connection . get_account_info ( address , encoding = \"base64\" , commitment = commitment , ) if not account_info . value : return None slot = account_info . context . slot data = account_info . value . data decoded_data = program . coder . accounts . decode ( data ) return DataAndSlot ( slot , decoded_data )","title":"get_account_data_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_all_perp_market_accounts","text":"Source code in driftpy/accounts/get_accounts.py async def get_all_perp_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"PerpMarket\" ] . all ()","title":"get_all_perp_market_accounts()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_all_spot_market_accounts","text":"Source code in driftpy/accounts/get_accounts.py async def get_all_spot_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"SpotMarket\" ] . all ()","title":"get_all_spot_market_accounts()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_if_stake_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_if_stake_account ( program : Program , authority : Pubkey , spot_market_index : int ) -> InsuranceFundStake : if_stake_pk = get_insurance_fund_stake_public_key ( program . program_id , authority , spot_market_index ) response = await program . account [ \"InsuranceFundStake\" ] . fetch ( if_stake_pk ) return cast ( InsuranceFundStake , response )","title":"get_if_stake_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_perp_market_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account ( program : Program , market_index : int ) -> PerpMarket : return ( await get_perp_market_account_and_slot ( program , market_index )) . data","title":"get_perp_market_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_perp_market_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account_and_slot ( program : Program , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: perp_market_public_key = get_perp_market_public_key ( program . program_id , market_index ) return await get_account_data_and_slot ( perp_market_public_key , program )","title":"get_perp_market_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_spot_market_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account ( program : Program , spot_market_index : int ) -> SpotMarket : return ( await get_spot_market_account_and_slot ( program , spot_market_index )) . data","title":"get_spot_market_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_spot_market_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account_and_slot ( program : Program , spot_market_index : int ) -> DataAndSlot [ SpotMarket ]: spot_market_public_key = get_spot_market_public_key ( program . program_id , spot_market_index ) return await get_account_data_and_slot ( spot_market_public_key , program )","title":"get_spot_market_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_state_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_state_account ( program : Program ) -> State : return ( await get_state_account_and_slot ( program )) . data","title":"get_state_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_state_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_state_account_and_slot ( program : Program ) -> DataAndSlot [ State ]: state_public_key = get_state_public_key ( program . program_id ) return await get_account_data_and_slot ( state_public_key , program )","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_account ( program : Program , user_public_key : Pubkey , ) -> User : return ( await get_user_account_and_slot ( program , user_public_key )) . data","title":"get_user_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_account_and_slot ( program : Program , user_public_key : Pubkey , ) -> DataAndSlot [ User ]: return await get_account_data_and_slot ( user_public_key , program )","title":"get_user_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_stats_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_stats_account ( program : Program , authority : Pubkey , ) -> UserStats : user_stats_public_key = get_user_stats_account_public_key ( program . program_id , authority , ) response = await program . account [ \"UserStats\" ] . fetch ( user_stats_public_key ) return cast ( UserStats , response )","title":"get_user_stats_account()"},{"location":"accounts/#driftpy.accounts.oracle","text":"","title":"oracle"},{"location":"accounts/#driftpy.accounts.oracle.convert_pyth_price","text":"Source code in driftpy/accounts/oracle.py def convert_pyth_price ( price , scale = 1 ): return int ( price * PRICE_PRECISION * scale )","title":"convert_pyth_price()"},{"location":"accounts/#driftpy.accounts.oracle.get_oracle_price_data_and_slot","text":"Source code in driftpy/accounts/oracle.py async def get_oracle_price_data_and_slot ( connection : AsyncClient , address : Pubkey , oracle_source = OracleSource . PYTH () ) -> DataAndSlot [ OraclePriceData ]: if \"Pyth\" in str ( oracle_source ): rpc_reponse = await connection . get_account_info ( address ) rpc_response_slot = rpc_reponse . context . slot ( pyth_price_info , last_slot , twac , twap ) = await _parse_pyth_price_info ( rpc_reponse ) scale = 1 if \"1K\" in str ( oracle_source ): scale = 1e3 elif \"1M\" in str ( oracle_source ): scale = 1e6 oracle_data = OraclePriceData ( price = convert_pyth_price ( pyth_price_info . price , scale ), slot = pyth_price_info . pub_slot , confidence = convert_pyth_price ( pyth_price_info . confidence_interval , scale ), twap = convert_pyth_price ( twap , scale ), twap_confidence = convert_pyth_price ( twac , scale ), has_sufficient_number_of_datapoints = True , ) return DataAndSlot ( data = oracle_data , slot = rpc_response_slot ) elif \"Quote\" in str ( oracle_source ): return DataAndSlot ( data = OraclePriceData ( PRICE_PRECISION , 0 , 1 , 1 , 0 , True ), slot = 0 ) else : raise NotImplementedError ( \"Unsupported Oracle Source\" , str ( oracle_source ))","title":"get_oracle_price_data_and_slot()"},{"location":"accounts/#driftpy.accounts.types","text":"","title":"types"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot","text":"DataAndSlot(slot: int, data: ~T) Source code in driftpy/accounts/types.py @dataclass class DataAndSlot ( Generic [ T ]): slot : int data : T","title":"DataAndSlot"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.data","text":"","title":"data"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.slot","text":"","title":"slot"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.__init__","text":"","title":"__init__()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber","text":"Source code in driftpy/accounts/types.py class DriftClientAccountSubscriber : @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass","title":"DriftClientAccountSubscriber"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_oracle_data_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass","title":"get_oracle_data_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_perp_market_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass","title":"get_perp_market_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_spot_market_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass","title":"get_spot_market_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_state_account_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.types.UserAccountSubscriber","text":"Source code in driftpy/accounts/types.py class UserAccountSubscriber : @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"UserAccountSubscriber"},{"location":"accounts/#driftpy.accounts.types.UserAccountSubscriber.get_user_account_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"get_user_account_and_slot()"},{"location":"addresses/","text":"Addresses These functions are used to derive on-chain addresses of the accounts (publickey of the sol-market) addresses get_drift_client_signer_public_key ( program_id ) Source code in driftpy/addresses.py def get_drift_client_signer_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_signer\" ], program_id )[ 0 ] get_insurance_fund_stake_public_key ( program_id , authority , spot_market_index ) Source code in driftpy/addresses.py def get_insurance_fund_stake_public_key ( program_id : Pubkey , authority : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_stake\" , bytes ( authority ), int_to_le_bytes ( spot_market_index )], program_id , )[ 0 ] get_insurance_fund_vault_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_insurance_fund_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_perp_market_public_key ( program_id , market_index ) Source code in driftpy/addresses.py def get_perp_market_public_key ( program_id : Pubkey , market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"perp_market\" , int_to_le_bytes ( market_index )], program_id )[ 0 ] get_spot_market_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_spot_market_vault_authority_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_vault_authority_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault_authority\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_spot_market_vault_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_state_public_key ( program_id ) Source code in driftpy/addresses.py def get_state_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_state\" ], program_id )[ 0 ] get_user_account_public_key ( program_id , authority , user_id = 0 ) Source code in driftpy/addresses.py def get_user_account_public_key ( program_id : Pubkey , authority : Pubkey , user_id = 0 , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"user\" , bytes ( authority ), int_to_le_bytes ( user_id )], program_id )[ 0 ] get_user_stats_account_public_key ( program_id , authority ) Source code in driftpy/addresses.py def get_user_stats_account_public_key ( program_id : Pubkey , authority : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"user_stats\" , bytes ( authority )], program_id )[ 0 ] int_to_le_bytes ( a ) Source code in driftpy/addresses.py def int_to_le_bytes ( a : int ): return a . to_bytes ( 2 , \"little\" )","title":"Addresses"},{"location":"addresses/#addresses","text":"These functions are used to derive on-chain addresses of the accounts (publickey of the sol-market)","title":"Addresses"},{"location":"addresses/#driftpy.addresses","text":"","title":"addresses"},{"location":"addresses/#driftpy.addresses.get_drift_client_signer_public_key","text":"Source code in driftpy/addresses.py def get_drift_client_signer_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_signer\" ], program_id )[ 0 ]","title":"get_drift_client_signer_public_key()"},{"location":"addresses/#driftpy.addresses.get_insurance_fund_stake_public_key","text":"Source code in driftpy/addresses.py def get_insurance_fund_stake_public_key ( program_id : Pubkey , authority : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_stake\" , bytes ( authority ), int_to_le_bytes ( spot_market_index )], program_id , )[ 0 ]","title":"get_insurance_fund_stake_public_key()"},{"location":"addresses/#driftpy.addresses.get_insurance_fund_vault_public_key","text":"Source code in driftpy/addresses.py def get_insurance_fund_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_insurance_fund_vault_public_key()"},{"location":"addresses/#driftpy.addresses.get_perp_market_public_key","text":"Source code in driftpy/addresses.py def get_perp_market_public_key ( program_id : Pubkey , market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"perp_market\" , int_to_le_bytes ( market_index )], program_id )[ 0 ]","title":"get_perp_market_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_vault_authority_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_vault_authority_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault_authority\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_vault_authority_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_vault_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_vault_public_key()"},{"location":"addresses/#driftpy.addresses.get_state_public_key","text":"Source code in driftpy/addresses.py def get_state_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_state\" ], program_id )[ 0 ]","title":"get_state_public_key()"},{"location":"addresses/#driftpy.addresses.get_user_account_public_key","text":"Source code in driftpy/addresses.py def get_user_account_public_key ( program_id : Pubkey , authority : Pubkey , user_id = 0 , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"user\" , bytes ( authority ), int_to_le_bytes ( user_id )], program_id )[ 0 ]","title":"get_user_account_public_key()"},{"location":"addresses/#driftpy.addresses.get_user_stats_account_public_key","text":"Source code in driftpy/addresses.py def get_user_stats_account_public_key ( program_id : Pubkey , authority : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"user_stats\" , bytes ( authority )], program_id )[ 0 ]","title":"get_user_stats_account_public_key()"},{"location":"addresses/#driftpy.addresses.int_to_le_bytes","text":"Source code in driftpy/addresses.py def int_to_le_bytes ( a : int ): return a . to_bytes ( 2 , \"little\" )","title":"int_to_le_bytes()"},{"location":"clearing_house/","text":"Drift Client This object is used to interact with the protocol (deposit, withdraw, trade, lp, etc.) Example drift_client = DriftClient . from_config ( config , provider ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) drift_client DEFAULT_USER_NAME DriftClient This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. Source code in driftpy/drift_client.py class DriftClient : \"\"\"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. \"\"\" def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] ) async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), ) __init__ ( self , program , signer = None , authority = None , account_subscriber = None , tx_params = None , tx_version = None ) special Initializes the drift client object -- likely want to use the .from_config method instead of this one Parameters: Name Type Description Default program Program Drift anchor program (see from_config on how to initialize it) required authority Keypair Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. None Source code in driftpy/drift_client.py def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy add_insurance_fund_stake ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) add_liquidity ( self , amount , market_index , user_id = 0 ) async mint LP tokens and add liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to mint required market_index int market you want to lp in required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) cancel_order ( self , order_id = None , user_id = 0 ) async cancel specific order (if order_id=None will be most recent order) Parameters: Name Type Description Default order_id Optional[int] Defaults to None. None user_id int subaccount id which contains order. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) cancel_orders ( self , user_id = 0 ) async cancel all existing orders on the book Parameters: Name Type Description Default user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) cancel_request_remove_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) close_position ( self , market_index , limit_price = 0 , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) default_order_params ( self , order_type , market_index , base_asset_amount , direction ) Source code in driftpy/drift_client.py def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) deposit ( self , amount , spot_market_index , user_token_account , user_id = 0 , reduce_only = False , user_initialized = True ) async deposits collateral into protocol Parameters: Name Type Description Default amount int amount to deposit required spot_market_index int required user_token_account Pubkey required user_id int subaccount to deposit into. Defaults to 0. 0 reduce_only bool paying back borrow vs depositing new assets. Defaults to False. False user_initialized bool if need to initialize user account too set this to False. Defaults to True. True Returns: Type Description str sig Source code in driftpy/drift_client.py async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) from_config ( config , provider , authority = None ) staticmethod Initializes the drift client object from a Config Parameters: Name Type Description Default config Config the config to initialize form required provider Provider anchor provider required authority Keypair description . Defaults to None. None Returns: Type Description DriftClient : the drift client object Source code in driftpy/drift_client.py @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client get_add_insurance_fund_stake_ix ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_add_liquidity_ix ( self , amount , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_order_ix ( self , order_id = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_orders_ix ( self , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) get_close_position_ix ( self , market_index , limit_price = 0 , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix get_deposit_collateral_ix ( self , amount , spot_market_index , user_token_account , user_id = 0 , reduce_only = False , user_initialized = True ) async Source code in driftpy/drift_client.py async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_increase_compute_ix ( self ) Source code in driftpy/drift_client.py def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix get_initialize_insurance_fund_stake_ix ( self , spot_market_index ) Source code in driftpy/drift_client.py def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) get_initialize_user_instructions ( self , user_id = 0 , name = 'Main Account' ) Source code in driftpy/drift_client.py def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix get_initialize_user_stats ( self ) Source code in driftpy/drift_client.py def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) get_liquidate_perp_ix ( self , user_authority , market_index , max_base_asset_amount , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority , perp_market_index , spot_market_index , max_pnl_transfer , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result get_liquidate_spot_ix ( self , user_authority , asset_market_index , liability_market_index , max_liability_transfer , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) get_open_position_ix ( self , direction , amount , market_index , user_id = 0 , limit_price = 0 , ioc = False ) async Source code in driftpy/drift_client.py async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix get_oracle_price_data ( self , oracle ) async Source code in driftpy/drift_client.py async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) get_perp_market ( self , market_index ) async Source code in driftpy/drift_client.py async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) get_place_and_take_ix ( self , order_params , maker_info = None , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_place_perp_order_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix get_place_perp_orders_ix ( self , order_params , user_id = 0 , cancel_all = True ) async Source code in driftpy/drift_client.py async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs get_place_spot_order_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix get_place_spot_orders_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs get_remaining_accounts ( self , writable_market_index = None , writable_spot_market_index = None , readable_spot_market_index = None , user_id = [ 0 ], include_oracles = True , include_spot_markets = True , authority = None ) async Source code in driftpy/drift_client.py async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts get_remove_insurance_fund_stake_ix ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) get_remove_liquidity_ix ( self , amount , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_request_remove_insurance_fund_stake_ix ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) get_resolve_perp_bankruptcy_ix ( self , user_authority , market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_resolve_spot_bankruptcy_ix ( self , user_authority , spot_market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_settle_expired_market_ix ( self , market_index ) async Source code in driftpy/drift_client.py async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_settle_lp_ix ( self , settlee_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) get_settle_pnl_ix ( self , user_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] get_spot_market ( self , market_index ) async Source code in driftpy/drift_client.py async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) get_state ( self ) async Source code in driftpy/drift_client.py async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) get_state_public_key ( self ) Source code in driftpy/drift_client.py def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) get_update_amm_ix ( self , market_indexs ) async Source code in driftpy/drift_client.py async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_user ( self , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) get_user_account_public_key ( self , user_id = 0 ) Source code in driftpy/drift_client.py def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) get_user_position ( self , market_index , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position get_user_spot_position ( self , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position get_user_stats_public_key ( self ) Source code in driftpy/drift_client.py def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) get_withdraw_collateral_ix ( self , amount , spot_market_index , user_token_account , reduce_only = False , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) initialize_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) intialize_user ( self , user_id = 0 ) async intializes a drift user Parameters: Name Type Description Default user_id int subaccount id to initialize. Defaults to 0. 0 Returns: Type Description str tx signature Source code in driftpy/drift_client.py async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) liquidate_perp ( self , user_authority , market_index , max_base_asset_amount , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) liquidate_perp_pnl_for_deposit ( self , user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) liquidate_spot ( self , user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) open_position ( self , direction , amount , market_index , user_id = 0 , limit_price = 0 , ioc = False ) async Source code in driftpy/drift_client.py async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) place_and_take ( self , order_params , maker_info = None , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) place_perp_order ( self , order_params , maker_info = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) place_spot_order ( self , order_params , maker_info = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) remove_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) remove_liquidity ( self , amount , market_index , user_id = 0 ) async burns LP tokens and removes liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to burn required market_index int required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) request_remove_insurance_fund_stake ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) resolve_perp_bankruptcy ( self , user_authority , market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) resolve_spot_bankruptcy ( self , user_authority , spot_market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) send_ixs ( self , ixs , signers = None ) async Source code in driftpy/drift_client.py async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) settle_expired_market ( self , market_index ) async Source code in driftpy/drift_client.py async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) settle_lp ( self , settlee_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) settle_pnl ( self , user_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) settle_revenue_to_insurance_fund ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), ) update_amm ( self , market_indexs ) async Source code in driftpy/drift_client.py async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) withdraw ( self , amount , spot_market_index , user_token_account , reduce_only = False , user_id = 0 ) async withdraws from drift protocol (can also allow borrowing) Parameters: Name Type Description Default amount int amount to withdraw required spot_market_index int required user_token_account Pubkey ata of the account to withdraw to required reduce_only bool if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. False user_id int subaccount. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] )","title":"Drift Client"},{"location":"clearing_house/#drift-client","text":"This object is used to interact with the protocol (deposit, withdraw, trade, lp, etc.)","title":"Drift Client"},{"location":"clearing_house/#example","text":"drift_client = DriftClient . from_config ( config , provider ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , )","title":"Example"},{"location":"clearing_house/#driftpy.drift_client","text":"","title":"drift_client"},{"location":"clearing_house/#driftpy.drift_client.DEFAULT_USER_NAME","text":"","title":"DEFAULT_USER_NAME"},{"location":"clearing_house/#driftpy.drift_client.DriftClient","text":"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. Source code in driftpy/drift_client.py class DriftClient : \"\"\"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. \"\"\" def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] ) async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), )","title":"DriftClient"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.__init__","text":"Initializes the drift client object -- likely want to use the .from_config method instead of this one Parameters: Name Type Description Default program Program Drift anchor program (see from_config on how to initialize it) required authority Keypair Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. None Source code in driftpy/drift_client.py def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy","title":"__init__()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.add_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) )","title":"add_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.add_liquidity","text":"mint LP tokens and add liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to mint required market_index int market you want to lp in required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] )","title":"add_liquidity()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_order","text":"cancel specific order (if order_id=None will be most recent order) Parameters: Name Type Description Default order_id Optional[int] Defaults to None. None user_id int subaccount id which contains order. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), )","title":"cancel_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_orders","text":"cancel all existing orders on the book Parameters: Name Type Description Default user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id ))","title":"cancel_orders()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_request_remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) )","title":"cancel_request_remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.close_position","text":"Source code in driftpy/drift_client.py async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) )","title":"close_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.default_order_params","text":"Source code in driftpy/drift_client.py def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , )","title":"default_order_params()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.deposit","text":"deposits collateral into protocol Parameters: Name Type Description Default amount int amount to deposit required spot_market_index int required user_token_account Pubkey required user_id int subaccount to deposit into. Defaults to 0. 0 reduce_only bool paying back borrow vs depositing new assets. Defaults to False. False user_initialized bool if need to initialize user account too set this to False. Defaults to True. True Returns: Type Description str sig Source code in driftpy/drift_client.py async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] )","title":"deposit()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.from_config","text":"Initializes the drift client object from a Config Parameters: Name Type Description Default config Config the config to initialize form required provider Provider anchor provider required authority Keypair description . Defaults to None. None Returns: Type Description DriftClient : the drift client object Source code in driftpy/drift_client.py @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client","title":"from_config()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_add_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_add_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_add_liquidity_ix","text":"Source code in driftpy/drift_client.py async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_add_liquidity_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_order_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_cancel_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_orders_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_cancel_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_request_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), )","title":"get_cancel_request_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_close_position_ix","text":"Source code in driftpy/drift_client.py async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix","title":"get_close_position_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_deposit_collateral_ix","text":"Source code in driftpy/drift_client.py async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_deposit_collateral_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_increase_compute_ix","text":"Source code in driftpy/drift_client.py def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix","title":"get_increase_compute_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), )","title":"get_initialize_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_user_instructions","text":"Source code in driftpy/drift_client.py def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix","title":"get_initialize_user_instructions()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_user_stats","text":"Source code in driftpy/drift_client.py def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), )","title":"get_initialize_user_stats()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_perp_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), )","title":"get_liquidate_perp_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_perp_pnl_for_deposit_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result","title":"get_liquidate_perp_pnl_for_deposit_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_spot_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), )","title":"get_liquidate_spot_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_open_position_ix","text":"Source code in driftpy/drift_client.py async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix","title":"get_open_position_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_oracle_price_data","text":"Source code in driftpy/drift_client.py async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None )","title":"get_oracle_price_data()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_perp_market","text":"Source code in driftpy/drift_client.py async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None )","title":"get_perp_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_and_take_ix","text":"Source code in driftpy/drift_client.py async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_place_and_take_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_perp_order_ix","text":"Source code in driftpy/drift_client.py async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix","title":"get_place_perp_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_perp_orders_ix","text":"Source code in driftpy/drift_client.py async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs","title":"get_place_perp_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_spot_order_ix","text":"Source code in driftpy/drift_client.py async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix","title":"get_place_spot_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_spot_orders_ix","text":"Source code in driftpy/drift_client.py async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs","title":"get_place_spot_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remaining_accounts","text":"Source code in driftpy/drift_client.py async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts","title":"get_remaining_accounts()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), )","title":"get_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remove_liquidity_ix","text":"Source code in driftpy/drift_client.py async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_remove_liquidity_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_request_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), )","title":"get_request_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_resolve_perp_bankruptcy_ix","text":"Source code in driftpy/drift_client.py async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_resolve_perp_bankruptcy_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_resolve_spot_bankruptcy_ix","text":"Source code in driftpy/drift_client.py async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_resolve_spot_bankruptcy_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_expired_market_ix","text":"Source code in driftpy/drift_client.py async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_settle_expired_market_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_lp_ix","text":"Source code in driftpy/drift_client.py async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), )","title":"get_settle_lp_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_pnl_ix","text":"Source code in driftpy/drift_client.py async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ]","title":"get_settle_pnl_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_spot_market","text":"Source code in driftpy/drift_client.py async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None )","title":"get_spot_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_state","text":"Source code in driftpy/drift_client.py async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None )","title":"get_state()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_state_public_key","text":"Source code in driftpy/drift_client.py def get_state_public_key ( self ): return get_state_public_key ( self . program_id )","title":"get_state_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_update_amm_ix","text":"Source code in driftpy/drift_client.py async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_update_amm_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user","text":"Source code in driftpy/drift_client.py async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) )","title":"get_user()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_account_public_key","text":"Source code in driftpy/drift_client.py def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id )","title":"get_user_account_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_position","text":"Source code in driftpy/drift_client.py async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position","title":"get_user_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_spot_position","text":"Source code in driftpy/drift_client.py async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"get_user_spot_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_stats_public_key","text":"Source code in driftpy/drift_client.py def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority )","title":"get_user_stats_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_withdraw_collateral_ix","text":"Source code in driftpy/drift_client.py async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_withdraw_collateral_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.initialize_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) )","title":"initialize_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.intialize_user","text":"intializes a drift user Parameters: Name Type Description Default user_id int subaccount id to initialize. Defaults to 0. 0 Returns: Type Description str tx signature Source code in driftpy/drift_client.py async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs )","title":"intialize_user()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_perp","text":"Source code in driftpy/drift_client.py async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] )","title":"liquidate_perp()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_perp_pnl_for_deposit","text":"Source code in driftpy/drift_client.py async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) )","title":"liquidate_perp_pnl_for_deposit()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_spot","text":"Source code in driftpy/drift_client.py async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] )","title":"liquidate_spot()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.open_position","text":"Source code in driftpy/drift_client.py async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), )","title":"open_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_and_take","text":"Source code in driftpy/drift_client.py async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] )","title":"place_and_take()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_perp_order","text":"Source code in driftpy/drift_client.py async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] )","title":"place_perp_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_spot_order","text":"Source code in driftpy/drift_client.py async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] )","title":"place_spot_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) )","title":"remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.remove_liquidity","text":"burns LP tokens and removes liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to burn required market_index int required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] )","title":"remove_liquidity()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.request_remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) )","title":"request_remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.resolve_perp_bankruptcy","text":"Source code in driftpy/drift_client.py async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] )","title":"resolve_perp_bankruptcy()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.resolve_spot_bankruptcy","text":"Source code in driftpy/drift_client.py async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] )","title":"resolve_spot_bankruptcy()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.send_ixs","text":"Source code in driftpy/drift_client.py async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx )","title":"send_ixs()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_expired_market","text":"Source code in driftpy/drift_client.py async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] )","title":"settle_expired_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_lp","text":"Source code in driftpy/drift_client.py async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], )","title":"settle_lp()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_pnl","text":"Source code in driftpy/drift_client.py async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) )","title":"settle_pnl()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_revenue_to_insurance_fund","text":"Source code in driftpy/drift_client.py async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), )","title":"settle_revenue_to_insurance_fund()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.update_amm","text":"Source code in driftpy/drift_client.py async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs ))","title":"update_amm()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.withdraw","text":"withdraws from drift protocol (can also allow borrowing) Parameters: Name Type Description Default amount int amount to withdraw required spot_market_index int required user_token_account Pubkey ata of the account to withdraw to required reduce_only bool if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. False user_id int subaccount. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] )","title":"withdraw()"},{"location":"clearing_house_user/","text":"User This object is used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) Example drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl ) drift_user DriftUser This class is the main way to retrieve and inspect drift user account data. Source code in driftpy/drift_user.py class DriftUser : \"\"\"This class is the main way to retrieve and inspect drift user account data.\"\"\" def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) async def get_state ( self ) -> State : return await self . drift_client . get_state () async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price __init__ ( self , drift_client , authority = None , subaccount_id = 0 , account_subscriber = None ) special Initialize the user object Parameters: Name Type Description Default drift_client(DriftClient) required for program_id, idl, things (keypair doesnt matter) required authority Optional[Pubkey] authority to investigate if None will use drift_client.authority None subaccount_id int subaccount of authority to investigate. Defaults to 0. 0 Source code in driftpy/drift_user.py def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber can_be_liquidated ( self ) async Source code in driftpy/drift_user.py async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req get_free_collateral ( self ) async Source code in driftpy/drift_user.py async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral get_leverage ( self , margin_category = None ) async Source code in driftpy/drift_user.py async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage get_margin_requirement ( self , margin_category , liquidation_buffer = 0 , include_open_orders = True , include_spot = True ) async Source code in driftpy/drift_user.py async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result get_open_orders ( self ) async Source code in driftpy/drift_user.py async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders get_perp_liq_price ( self , perp_market_index ) async Source code in driftpy/drift_user.py async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price get_perp_market ( self , market_index ) async Source code in driftpy/drift_user.py async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) get_perp_oracle_data ( self , perp_market ) async Source code in driftpy/drift_user.py async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) get_spot_liq_price ( self , spot_market_index ) async Source code in driftpy/drift_user.py async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price get_spot_market ( self , market_index ) async Source code in driftpy/drift_user.py async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) get_spot_market_asset_value ( self , margin_category = None , include_open_orders = True , market_index = None ) async Source code in driftpy/drift_user.py async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None ) async Source code in driftpy/drift_user.py async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability get_spot_oracle_data ( self , spot_market ) async Source code in driftpy/drift_user.py async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) get_state ( self ) async Source code in driftpy/drift_user.py async def get_state ( self ) -> State : return await self . drift_client . get_state () get_total_collateral ( self , margin_category = None ) async Source code in driftpy/drift_user.py async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral get_total_perp_liability ( self , margin_category = None , liquidation_buffer = 0 , include_open_orders = False ) async Source code in driftpy/drift_user.py async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl get_unrealized_pnl ( self , with_funding = False , market_index = None , with_weight_margin_category = None ) async Source code in driftpy/drift_user.py async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl get_user ( self ) async Source code in driftpy/drift_user.py async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data get_user_position ( self , market_index ) async Source code in driftpy/drift_user.py async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position get_user_spot_position ( self , market_index ) async Source code in driftpy/drift_user.py async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"User"},{"location":"clearing_house_user/#user","text":"This object is used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.)","title":"User"},{"location":"clearing_house_user/#example","text":"drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Example"},{"location":"clearing_house_user/#driftpy.drift_user","text":"","title":"drift_user"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser","text":"This class is the main way to retrieve and inspect drift user account data. Source code in driftpy/drift_user.py class DriftUser : \"\"\"This class is the main way to retrieve and inspect drift user account data.\"\"\" def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) async def get_state ( self ) -> State : return await self . drift_client . get_state () async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price","title":"DriftUser"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.__init__","text":"Initialize the user object Parameters: Name Type Description Default drift_client(DriftClient) required for program_id, idl, things (keypair doesnt matter) required authority Optional[Pubkey] authority to investigate if None will use drift_client.authority None subaccount_id int subaccount of authority to investigate. Defaults to 0. 0 Source code in driftpy/drift_user.py def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber","title":"__init__()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.can_be_liquidated","text":"Source code in driftpy/drift_user.py async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req","title":"can_be_liquidated()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_free_collateral","text":"Source code in driftpy/drift_user.py async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral","title":"get_free_collateral()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_leverage","text":"Source code in driftpy/drift_user.py async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage","title":"get_leverage()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_margin_requirement","text":"Source code in driftpy/drift_user.py async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result","title":"get_margin_requirement()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_open_orders","text":"Source code in driftpy/drift_user.py async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders","title":"get_open_orders()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_liq_price","text":"Source code in driftpy/drift_user.py async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price","title":"get_perp_liq_price()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_market","text":"Source code in driftpy/drift_user.py async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index )","title":"get_perp_market()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_oracle_data","text":"Source code in driftpy/drift_user.py async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle )","title":"get_perp_oracle_data()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_liq_price","text":"Source code in driftpy/drift_user.py async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price","title":"get_spot_liq_price()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market","text":"Source code in driftpy/drift_user.py async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index )","title":"get_spot_market()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market_asset_value","text":"Source code in driftpy/drift_user.py async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value","title":"get_spot_market_asset_value()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market_liability","text":"Source code in driftpy/drift_user.py async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability","title":"get_spot_market_liability()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_oracle_data","text":"Source code in driftpy/drift_user.py async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle )","title":"get_spot_oracle_data()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_state","text":"Source code in driftpy/drift_user.py async def get_state ( self ) -> State : return await self . drift_client . get_state ()","title":"get_state()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_total_collateral","text":"Source code in driftpy/drift_user.py async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral","title":"get_total_collateral()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_total_perp_liability","text":"Source code in driftpy/drift_user.py async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl","title":"get_total_perp_liability()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_unrealized_pnl","text":"Source code in driftpy/drift_user.py async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl","title":"get_unrealized_pnl()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user","text":"Source code in driftpy/drift_user.py async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data","title":"get_user()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user_position","text":"Source code in driftpy/drift_user.py async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position","title":"get_user_position()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user_spot_position","text":"Source code in driftpy/drift_user.py async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"get_user_spot_position()"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Drift-v2 Python SDK DriftPy is the Python SDK for Drift-v2 on Solana. It allows you to trade and fetch data from Drift using Python. Installation pip install driftpy Note: requires Python >= 3.10. Key Components DriftClient / drift_client.py : Used to interact with the protocol (deposit, withdraw, trade, lp, etc.) DriftUser / drift_user.py : Used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) accounts.py : Used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) addresses.py : Used to derive on-chain addresses of the accounts (publickey of the sol-market) Example from solana.keypair import Keypair from driftpy.drift_client import DriftClient from driftpy.drift_user import User from driftpy.constants.numeric_constants import BASE_PRECISION , AMM_RESERVE_PRECISION from anchorpy import Provider , Wallet from solana.rpc.async_api import AsyncClient # load keypair from file KEYPATH = '../your-keypair-secret.json' with open ( KEYPATH , 'r' ) as f : secret = json . load ( f ) kp = Keypair . from_secret_key ( bytes ( secret )) # create clearing house for mainnet ENV = 'mainnet' config = configs [ ENV ] wallet = Wallet ( kp ) connection = AsyncClient ( config . default_http ) provider = Provider ( connection , wallet ) drift_client = DriftClient . from_config ( config , provider ) drift_user = DriftUser ( drift_client ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # clearing house user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Drift-v2 Python SDK"},{"location":"#drift-v2-python-sdk","text":"DriftPy is the Python SDK for Drift-v2 on Solana. It allows you to trade and fetch data from Drift using Python.","title":"Drift-v2 Python SDK"},{"location":"#installation","text":"pip install driftpy Note: requires Python >= 3.10.","title":"Installation"},{"location":"#key-components","text":"DriftClient / drift_client.py : Used to interact with the protocol (deposit, withdraw, trade, lp, etc.) DriftUser / drift_user.py : Used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) accounts.py : Used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) addresses.py : Used to derive on-chain addresses of the accounts (publickey of the sol-market)","title":"Key Components"},{"location":"#example","text":"from solana.keypair import Keypair from driftpy.drift_client import DriftClient from driftpy.drift_user import User from driftpy.constants.numeric_constants import BASE_PRECISION , AMM_RESERVE_PRECISION from anchorpy import Provider , Wallet from solana.rpc.async_api import AsyncClient # load keypair from file KEYPATH = '../your-keypair-secret.json' with open ( KEYPATH , 'r' ) as f : secret = json . load ( f ) kp = Keypair . from_secret_key ( bytes ( secret )) # create clearing house for mainnet ENV = 'mainnet' config = configs [ ENV ] wallet = Wallet ( kp ) connection = AsyncClient ( config . default_http ) provider = Provider ( connection , wallet ) drift_client = DriftClient . from_config ( config , provider ) drift_user = DriftUser ( drift_client ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # clearing house user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Example"},{"location":"accounts/","text":"Accounts These functions are used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.) Example drift_client = DriftClient . from_config ( config , provider ) # get sol market info sol_market_index = 0 sol_market = await get_perp_market_account ( drift_client . program , sol_market_index ) print ( sol_market . amm . sqrt_k , sol_market . amm . base_asset_amount_long , sol_market . amm . base_asset_amount_short , ) # get usdc spot market info usdc_spot_market_index = 0 usdc_market = await get_spot_market_account ( drift_client . program , usdc_spot_market_index ) print ( usdc . market_index , usdc . deposit_balance , usdc . borrow_balance , ) accounts special cache special drift_client CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ) Source code in driftpy/accounts/cache/drift_client.py class CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ): def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] async def cache_if_needed ( self ): if self . cache is None : await self . update_cache () __init__ ( self , program , commitment = 'confirmed' ) special Source code in driftpy/accounts/cache/drift_client.py def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None cache_if_needed ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def cache_if_needed ( self ): if self . cache is None : await self . update_cache () get_oracle_data_and_slot ( self , oracle ) async Source code in driftpy/accounts/cache/drift_client.py async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] get_perp_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/cache/drift_client.py async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] get_spot_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/cache/drift_client.py async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] get_state_account_and_slot ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] update_cache ( self ) async Source code in driftpy/accounts/cache/drift_client.py async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data user CachedUserAccountSubscriber ( UserAccountSubscriber ) Source code in driftpy/accounts/cache/user.py class CachedUserAccountSubscriber ( UserAccountSubscriber ): def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache () __init__ ( self , user_pubkey , program , commitment = 'confirmed' ) special Source code in driftpy/accounts/cache/user.py def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None cache_if_needed ( self ) async Source code in driftpy/accounts/cache/user.py async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache () get_user_account_and_slot ( self ) async Source code in driftpy/accounts/cache/user.py async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot update_cache ( self ) async Source code in driftpy/accounts/cache/user.py async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot get_accounts get_account_data_and_slot ( address , program , commitment = 'processed' ) async Source code in driftpy/accounts/get_accounts.py async def get_account_data_and_slot ( address : Pubkey , program : Program , commitment : Commitment = \"processed\" ) -> Optional [ DataAndSlot [ T ]]: account_info = await program . provider . connection . get_account_info ( address , encoding = \"base64\" , commitment = commitment , ) if not account_info . value : return None slot = account_info . context . slot data = account_info . value . data decoded_data = program . coder . accounts . decode ( data ) return DataAndSlot ( slot , decoded_data ) get_all_perp_market_accounts ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_all_perp_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"PerpMarket\" ] . all () get_all_spot_market_accounts ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_all_spot_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"SpotMarket\" ] . all () get_if_stake_account ( program , authority , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_if_stake_account ( program : Program , authority : Pubkey , spot_market_index : int ) -> InsuranceFundStake : if_stake_pk = get_insurance_fund_stake_public_key ( program . program_id , authority , spot_market_index ) response = await program . account [ \"InsuranceFundStake\" ] . fetch ( if_stake_pk ) return cast ( InsuranceFundStake , response ) get_perp_market_account ( program , market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account ( program : Program , market_index : int ) -> PerpMarket : return ( await get_perp_market_account_and_slot ( program , market_index )) . data get_perp_market_account_and_slot ( program , market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account_and_slot ( program : Program , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: perp_market_public_key = get_perp_market_public_key ( program . program_id , market_index ) return await get_account_data_and_slot ( perp_market_public_key , program ) get_spot_market_account ( program , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account ( program : Program , spot_market_index : int ) -> SpotMarket : return ( await get_spot_market_account_and_slot ( program , spot_market_index )) . data get_spot_market_account_and_slot ( program , spot_market_index ) async Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account_and_slot ( program : Program , spot_market_index : int ) -> DataAndSlot [ SpotMarket ]: spot_market_public_key = get_spot_market_public_key ( program . program_id , spot_market_index ) return await get_account_data_and_slot ( spot_market_public_key , program ) get_state_account ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_state_account ( program : Program ) -> State : return ( await get_state_account_and_slot ( program )) . data get_state_account_and_slot ( program ) async Source code in driftpy/accounts/get_accounts.py async def get_state_account_and_slot ( program : Program ) -> DataAndSlot [ State ]: state_public_key = get_state_public_key ( program . program_id ) return await get_account_data_and_slot ( state_public_key , program ) get_user_account ( program , user_public_key ) async Source code in driftpy/accounts/get_accounts.py async def get_user_account ( program : Program , user_public_key : Pubkey , ) -> User : return ( await get_user_account_and_slot ( program , user_public_key )) . data get_user_account_and_slot ( program , user_public_key ) async Source code in driftpy/accounts/get_accounts.py async def get_user_account_and_slot ( program : Program , user_public_key : Pubkey , ) -> DataAndSlot [ User ]: return await get_account_data_and_slot ( user_public_key , program ) get_user_stats_account ( program , authority ) async Source code in driftpy/accounts/get_accounts.py async def get_user_stats_account ( program : Program , authority : Pubkey , ) -> UserStats : user_stats_public_key = get_user_stats_account_public_key ( program . program_id , authority , ) response = await program . account [ \"UserStats\" ] . fetch ( user_stats_public_key ) return cast ( UserStats , response ) oracle convert_pyth_price ( price , scale = 1 ) Source code in driftpy/accounts/oracle.py def convert_pyth_price ( price , scale = 1 ): return int ( price * PRICE_PRECISION * scale ) get_oracle_price_data_and_slot ( connection , address , oracle_source = OracleSource . PYTH ()) async Source code in driftpy/accounts/oracle.py async def get_oracle_price_data_and_slot ( connection : AsyncClient , address : Pubkey , oracle_source = OracleSource . PYTH () ) -> DataAndSlot [ OraclePriceData ]: if \"Pyth\" in str ( oracle_source ): rpc_reponse = await connection . get_account_info ( address ) rpc_response_slot = rpc_reponse . context . slot ( pyth_price_info , last_slot , twac , twap ) = await _parse_pyth_price_info ( rpc_reponse ) scale = 1 if \"1K\" in str ( oracle_source ): scale = 1e3 elif \"1M\" in str ( oracle_source ): scale = 1e6 oracle_data = OraclePriceData ( price = convert_pyth_price ( pyth_price_info . price , scale ), slot = pyth_price_info . pub_slot , confidence = convert_pyth_price ( pyth_price_info . confidence_interval , scale ), twap = convert_pyth_price ( twap , scale ), twap_confidence = convert_pyth_price ( twac , scale ), has_sufficient_number_of_datapoints = True , ) return DataAndSlot ( data = oracle_data , slot = rpc_response_slot ) elif \"Quote\" in str ( oracle_source ): return DataAndSlot ( data = OraclePriceData ( PRICE_PRECISION , 0 , 1 , 1 , 0 , True ), slot = 0 ) else : raise NotImplementedError ( \"Unsupported Oracle Source\" , str ( oracle_source )) types DataAndSlot ( Generic ) dataclass DataAndSlot(slot: int, data: ~T) Source code in driftpy/accounts/types.py @dataclass class DataAndSlot ( Generic [ T ]): slot : int data : T data : ~ T dataclass-field slot : int dataclass-field __init__ ( self , slot , data ) special DriftClientAccountSubscriber Source code in driftpy/accounts/types.py class DriftClientAccountSubscriber : @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass get_oracle_data_and_slot ( self , oracle ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass get_perp_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass get_spot_market_and_slot ( self , market_index ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass get_state_account_and_slot ( self ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass UserAccountSubscriber Source code in driftpy/accounts/types.py class UserAccountSubscriber : @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass get_user_account_and_slot ( self ) async Source code in driftpy/accounts/types.py @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"Accounts"},{"location":"accounts/#accounts","text":"These functions are used to retrieve specific on-chain accounts (State, PerpMarket, SpotMarket, etc.)","title":"Accounts"},{"location":"accounts/#example","text":"drift_client = DriftClient . from_config ( config , provider ) # get sol market info sol_market_index = 0 sol_market = await get_perp_market_account ( drift_client . program , sol_market_index ) print ( sol_market . amm . sqrt_k , sol_market . amm . base_asset_amount_long , sol_market . amm . base_asset_amount_short , ) # get usdc spot market info usdc_spot_market_index = 0 usdc_market = await get_spot_market_account ( drift_client . program , usdc_spot_market_index ) print ( usdc . market_index , usdc . deposit_balance , usdc . borrow_balance , )","title":"Example"},{"location":"accounts/#driftpy.accounts","text":"","title":"accounts"},{"location":"accounts/#driftpy.accounts.cache","text":"","title":"cache"},{"location":"accounts/#driftpy.accounts.cache.drift_client","text":"","title":"drift_client"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber","text":"Source code in driftpy/accounts/cache/drift_client.py class CachedDriftClientAccountSubscriber ( DriftClientAccountSubscriber ): def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ] async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ] async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ] async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )] async def cache_if_needed ( self ): if self . cache is None : await self . update_cache ()","title":"CachedDriftClientAccountSubscriber"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.__init__","text":"Source code in driftpy/accounts/cache/drift_client.py def __init__ ( self , program : Program , commitment : Commitment = \"confirmed\" ): self . program = program self . commitment = commitment self . cache = None","title":"__init__()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.cache_if_needed","text":"Source code in driftpy/accounts/cache/drift_client.py async def cache_if_needed ( self ): if self . cache is None : await self . update_cache ()","title":"cache_if_needed()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_oracle_data_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: await self . cache_if_needed () return self . cache [ \"oracle_price_data\" ][ str ( oracle )]","title":"get_oracle_data_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_perp_market_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: await self . cache_if_needed () return self . cache [ \"perp_markets\" ][ market_index ]","title":"get_perp_market_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_spot_market_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: await self . cache_if_needed () return self . cache [ \"spot_markets\" ][ market_index ]","title":"get_spot_market_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.get_state_account_and_slot","text":"Source code in driftpy/accounts/cache/drift_client.py async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: await self . cache_if_needed () return self . cache [ \"state\" ]","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.drift_client.CachedDriftClientAccountSubscriber.update_cache","text":"Source code in driftpy/accounts/cache/drift_client.py async def update_cache ( self ): if self . cache is None : self . cache = {} state_and_slot = await get_state_account_and_slot ( self . program ) self . cache [ \"state\" ] = state_and_slot oracle_data = {} spot_markets = [] for i in range ( state_and_slot . data . number_of_spot_markets ): spot_market_and_slot = await get_spot_market_account_and_slot ( self . program , i ) spot_markets . append ( spot_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , spot_market_and_slot . data . oracle , spot_market_and_slot . data . oracle_source , ) oracle_data [ str ( spot_market_and_slot . data . oracle ) ] = oracle_price_data_and_slot self . cache [ \"spot_markets\" ] = spot_markets perp_markets = [] for i in range ( state_and_slot . data . number_of_markets ): perp_market_and_slot = await get_perp_market_account_and_slot ( self . program , i ) perp_markets . append ( perp_market_and_slot ) oracle_price_data_and_slot = await get_oracle_price_data_and_slot ( self . program . provider . connection , perp_market_and_slot . data . amm . oracle , perp_market_and_slot . data . amm . oracle_source , ) oracle_data [ str ( perp_market_and_slot . data . amm . oracle ) ] = oracle_price_data_and_slot self . cache [ \"perp_markets\" ] = perp_markets self . cache [ \"oracle_price_data\" ] = oracle_data","title":"update_cache()"},{"location":"accounts/#driftpy.accounts.cache.user","text":"","title":"user"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber","text":"Source code in driftpy/accounts/cache/user.py class CachedUserAccountSubscriber ( UserAccountSubscriber ): def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache ()","title":"CachedUserAccountSubscriber"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.__init__","text":"Source code in driftpy/accounts/cache/user.py def __init__ ( self , user_pubkey : Pubkey , program : Program , commitment : Commitment = \"confirmed\" , ): self . program = program self . commitment = commitment self . user_pubkey = user_pubkey self . user_and_slot = None","title":"__init__()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.cache_if_needed","text":"Source code in driftpy/accounts/cache/user.py async def cache_if_needed ( self ): if self . user_and_slot is None : await self . update_cache ()","title":"cache_if_needed()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.get_user_account_and_slot","text":"Source code in driftpy/accounts/cache/user.py async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: await self . cache_if_needed () return self . user_and_slot","title":"get_user_account_and_slot()"},{"location":"accounts/#driftpy.accounts.cache.user.CachedUserAccountSubscriber.update_cache","text":"Source code in driftpy/accounts/cache/user.py async def update_cache ( self ): user_and_slot = await get_user_account_and_slot ( self . program , self . user_pubkey ) self . user_and_slot = user_and_slot","title":"update_cache()"},{"location":"accounts/#driftpy.accounts.get_accounts","text":"","title":"get_accounts"},{"location":"accounts/#driftpy.accounts.get_accounts.get_account_data_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_account_data_and_slot ( address : Pubkey , program : Program , commitment : Commitment = \"processed\" ) -> Optional [ DataAndSlot [ T ]]: account_info = await program . provider . connection . get_account_info ( address , encoding = \"base64\" , commitment = commitment , ) if not account_info . value : return None slot = account_info . context . slot data = account_info . value . data decoded_data = program . coder . accounts . decode ( data ) return DataAndSlot ( slot , decoded_data )","title":"get_account_data_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_all_perp_market_accounts","text":"Source code in driftpy/accounts/get_accounts.py async def get_all_perp_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"PerpMarket\" ] . all ()","title":"get_all_perp_market_accounts()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_all_spot_market_accounts","text":"Source code in driftpy/accounts/get_accounts.py async def get_all_spot_market_accounts ( program : Program ) -> list [ ProgramAccount ]: return await program . account [ \"SpotMarket\" ] . all ()","title":"get_all_spot_market_accounts()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_if_stake_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_if_stake_account ( program : Program , authority : Pubkey , spot_market_index : int ) -> InsuranceFundStake : if_stake_pk = get_insurance_fund_stake_public_key ( program . program_id , authority , spot_market_index ) response = await program . account [ \"InsuranceFundStake\" ] . fetch ( if_stake_pk ) return cast ( InsuranceFundStake , response )","title":"get_if_stake_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_perp_market_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account ( program : Program , market_index : int ) -> PerpMarket : return ( await get_perp_market_account_and_slot ( program , market_index )) . data","title":"get_perp_market_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_perp_market_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_perp_market_account_and_slot ( program : Program , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: perp_market_public_key = get_perp_market_public_key ( program . program_id , market_index ) return await get_account_data_and_slot ( perp_market_public_key , program )","title":"get_perp_market_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_spot_market_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account ( program : Program , spot_market_index : int ) -> SpotMarket : return ( await get_spot_market_account_and_slot ( program , spot_market_index )) . data","title":"get_spot_market_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_spot_market_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_spot_market_account_and_slot ( program : Program , spot_market_index : int ) -> DataAndSlot [ SpotMarket ]: spot_market_public_key = get_spot_market_public_key ( program . program_id , spot_market_index ) return await get_account_data_and_slot ( spot_market_public_key , program )","title":"get_spot_market_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_state_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_state_account ( program : Program ) -> State : return ( await get_state_account_and_slot ( program )) . data","title":"get_state_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_state_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_state_account_and_slot ( program : Program ) -> DataAndSlot [ State ]: state_public_key = get_state_public_key ( program . program_id ) return await get_account_data_and_slot ( state_public_key , program )","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_account ( program : Program , user_public_key : Pubkey , ) -> User : return ( await get_user_account_and_slot ( program , user_public_key )) . data","title":"get_user_account()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_account_and_slot","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_account_and_slot ( program : Program , user_public_key : Pubkey , ) -> DataAndSlot [ User ]: return await get_account_data_and_slot ( user_public_key , program )","title":"get_user_account_and_slot()"},{"location":"accounts/#driftpy.accounts.get_accounts.get_user_stats_account","text":"Source code in driftpy/accounts/get_accounts.py async def get_user_stats_account ( program : Program , authority : Pubkey , ) -> UserStats : user_stats_public_key = get_user_stats_account_public_key ( program . program_id , authority , ) response = await program . account [ \"UserStats\" ] . fetch ( user_stats_public_key ) return cast ( UserStats , response )","title":"get_user_stats_account()"},{"location":"accounts/#driftpy.accounts.oracle","text":"","title":"oracle"},{"location":"accounts/#driftpy.accounts.oracle.convert_pyth_price","text":"Source code in driftpy/accounts/oracle.py def convert_pyth_price ( price , scale = 1 ): return int ( price * PRICE_PRECISION * scale )","title":"convert_pyth_price()"},{"location":"accounts/#driftpy.accounts.oracle.get_oracle_price_data_and_slot","text":"Source code in driftpy/accounts/oracle.py async def get_oracle_price_data_and_slot ( connection : AsyncClient , address : Pubkey , oracle_source = OracleSource . PYTH () ) -> DataAndSlot [ OraclePriceData ]: if \"Pyth\" in str ( oracle_source ): rpc_reponse = await connection . get_account_info ( address ) rpc_response_slot = rpc_reponse . context . slot ( pyth_price_info , last_slot , twac , twap ) = await _parse_pyth_price_info ( rpc_reponse ) scale = 1 if \"1K\" in str ( oracle_source ): scale = 1e3 elif \"1M\" in str ( oracle_source ): scale = 1e6 oracle_data = OraclePriceData ( price = convert_pyth_price ( pyth_price_info . price , scale ), slot = pyth_price_info . pub_slot , confidence = convert_pyth_price ( pyth_price_info . confidence_interval , scale ), twap = convert_pyth_price ( twap , scale ), twap_confidence = convert_pyth_price ( twac , scale ), has_sufficient_number_of_datapoints = True , ) return DataAndSlot ( data = oracle_data , slot = rpc_response_slot ) elif \"Quote\" in str ( oracle_source ): return DataAndSlot ( data = OraclePriceData ( PRICE_PRECISION , 0 , 1 , 1 , 0 , True ), slot = 0 ) else : raise NotImplementedError ( \"Unsupported Oracle Source\" , str ( oracle_source ))","title":"get_oracle_price_data_and_slot()"},{"location":"accounts/#driftpy.accounts.types","text":"","title":"types"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot","text":"DataAndSlot(slot: int, data: ~T) Source code in driftpy/accounts/types.py @dataclass class DataAndSlot ( Generic [ T ]): slot : int data : T","title":"DataAndSlot"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.data","text":"","title":"data"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.slot","text":"","title":"slot"},{"location":"accounts/#driftpy.accounts.types.DataAndSlot.__init__","text":"","title":"__init__()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber","text":"Source code in driftpy/accounts/types.py class DriftClientAccountSubscriber : @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass","title":"DriftClientAccountSubscriber"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_oracle_data_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_oracle_data_and_slot ( self , oracle : Pubkey ) -> Optional [ DataAndSlot [ OraclePriceData ]]: pass","title":"get_oracle_data_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_perp_market_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_perp_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ PerpMarket ]]: pass","title":"get_perp_market_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_spot_market_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_spot_market_and_slot ( self , market_index : int ) -> Optional [ DataAndSlot [ SpotMarket ]]: pass","title":"get_spot_market_and_slot()"},{"location":"accounts/#driftpy.accounts.types.DriftClientAccountSubscriber.get_state_account_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_state_account_and_slot ( self ) -> Optional [ DataAndSlot [ State ]]: pass","title":"get_state_account_and_slot()"},{"location":"accounts/#driftpy.accounts.types.UserAccountSubscriber","text":"Source code in driftpy/accounts/types.py class UserAccountSubscriber : @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"UserAccountSubscriber"},{"location":"accounts/#driftpy.accounts.types.UserAccountSubscriber.get_user_account_and_slot","text":"Source code in driftpy/accounts/types.py @abstractmethod async def get_user_account_and_slot ( self ) -> Optional [ DataAndSlot [ User ]]: pass","title":"get_user_account_and_slot()"},{"location":"addresses/","text":"Addresses These functions are used to derive on-chain addresses of the accounts (publickey of the sol-market) addresses get_drift_client_signer_public_key ( program_id ) Source code in driftpy/addresses.py def get_drift_client_signer_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_signer\" ], program_id )[ 0 ] get_insurance_fund_stake_public_key ( program_id , authority , spot_market_index ) Source code in driftpy/addresses.py def get_insurance_fund_stake_public_key ( program_id : Pubkey , authority : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_stake\" , bytes ( authority ), int_to_le_bytes ( spot_market_index )], program_id , )[ 0 ] get_insurance_fund_vault_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_insurance_fund_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_perp_market_public_key ( program_id , market_index ) Source code in driftpy/addresses.py def get_perp_market_public_key ( program_id : Pubkey , market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"perp_market\" , int_to_le_bytes ( market_index )], program_id )[ 0 ] get_spot_market_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_spot_market_vault_authority_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_vault_authority_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault_authority\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_spot_market_vault_public_key ( program_id , spot_market_index ) Source code in driftpy/addresses.py def get_spot_market_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ] get_state_public_key ( program_id ) Source code in driftpy/addresses.py def get_state_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_state\" ], program_id )[ 0 ] get_user_account_public_key ( program_id , authority , user_id = 0 ) Source code in driftpy/addresses.py def get_user_account_public_key ( program_id : Pubkey , authority : Pubkey , user_id = 0 , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"user\" , bytes ( authority ), int_to_le_bytes ( user_id )], program_id )[ 0 ] get_user_stats_account_public_key ( program_id , authority ) Source code in driftpy/addresses.py def get_user_stats_account_public_key ( program_id : Pubkey , authority : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"user_stats\" , bytes ( authority )], program_id )[ 0 ] int_to_le_bytes ( a ) Source code in driftpy/addresses.py def int_to_le_bytes ( a : int ): return a . to_bytes ( 2 , \"little\" )","title":"Addresses"},{"location":"addresses/#addresses","text":"These functions are used to derive on-chain addresses of the accounts (publickey of the sol-market)","title":"Addresses"},{"location":"addresses/#driftpy.addresses","text":"","title":"addresses"},{"location":"addresses/#driftpy.addresses.get_drift_client_signer_public_key","text":"Source code in driftpy/addresses.py def get_drift_client_signer_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_signer\" ], program_id )[ 0 ]","title":"get_drift_client_signer_public_key()"},{"location":"addresses/#driftpy.addresses.get_insurance_fund_stake_public_key","text":"Source code in driftpy/addresses.py def get_insurance_fund_stake_public_key ( program_id : Pubkey , authority : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_stake\" , bytes ( authority ), int_to_le_bytes ( spot_market_index )], program_id , )[ 0 ]","title":"get_insurance_fund_stake_public_key()"},{"location":"addresses/#driftpy.addresses.get_insurance_fund_vault_public_key","text":"Source code in driftpy/addresses.py def get_insurance_fund_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"insurance_fund_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_insurance_fund_vault_public_key()"},{"location":"addresses/#driftpy.addresses.get_perp_market_public_key","text":"Source code in driftpy/addresses.py def get_perp_market_public_key ( program_id : Pubkey , market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"perp_market\" , int_to_le_bytes ( market_index )], program_id )[ 0 ]","title":"get_perp_market_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_vault_authority_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_vault_authority_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault_authority\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_vault_authority_public_key()"},{"location":"addresses/#driftpy.addresses.get_spot_market_vault_public_key","text":"Source code in driftpy/addresses.py def get_spot_market_vault_public_key ( program_id : Pubkey , spot_market_index : int , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"spot_market_vault\" , int_to_le_bytes ( spot_market_index )], program_id )[ 0 ]","title":"get_spot_market_vault_public_key()"},{"location":"addresses/#driftpy.addresses.get_state_public_key","text":"Source code in driftpy/addresses.py def get_state_public_key ( program_id : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"drift_state\" ], program_id )[ 0 ]","title":"get_state_public_key()"},{"location":"addresses/#driftpy.addresses.get_user_account_public_key","text":"Source code in driftpy/addresses.py def get_user_account_public_key ( program_id : Pubkey , authority : Pubkey , user_id = 0 , ) -> Pubkey : return Pubkey . find_program_address ( [ b \"user\" , bytes ( authority ), int_to_le_bytes ( user_id )], program_id )[ 0 ]","title":"get_user_account_public_key()"},{"location":"addresses/#driftpy.addresses.get_user_stats_account_public_key","text":"Source code in driftpy/addresses.py def get_user_stats_account_public_key ( program_id : Pubkey , authority : Pubkey , ) -> Pubkey : return Pubkey . find_program_address ([ b \"user_stats\" , bytes ( authority )], program_id )[ 0 ]","title":"get_user_stats_account_public_key()"},{"location":"addresses/#driftpy.addresses.int_to_le_bytes","text":"Source code in driftpy/addresses.py def int_to_le_bytes ( a : int ): return a . to_bytes ( 2 , \"little\" )","title":"int_to_le_bytes()"},{"location":"clearing_house/","text":"Drift Client This object is used to interact with the protocol (deposit, withdraw, trade, lp, etc.) Example drift_client = DriftClient . from_config ( config , provider ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , ) drift_client DEFAULT_USER_NAME DriftClient This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. Source code in driftpy/drift_client.py class DriftClient : \"\"\"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. \"\"\" def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] ) async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), ) __init__ ( self , program , signer = None , authority = None , account_subscriber = None , tx_params = None , tx_version = None ) special Initializes the drift client object -- likely want to use the .from_config method instead of this one Parameters: Name Type Description Default program Program Drift anchor program (see from_config on how to initialize it) required authority Keypair Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. None Source code in driftpy/drift_client.py def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy add_insurance_fund_stake ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) add_liquidity ( self , amount , market_index , user_id = 0 ) async mint LP tokens and add liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to mint required market_index int market you want to lp in required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) cancel_order ( self , order_id = None , user_id = 0 ) async cancel specific order (if order_id=None will be most recent order) Parameters: Name Type Description Default order_id Optional[int] Defaults to None. None user_id int subaccount id which contains order. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) cancel_orders ( self , user_id = 0 ) async cancel all existing orders on the book Parameters: Name Type Description Default user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) cancel_request_remove_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) close_position ( self , market_index , limit_price = 0 , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) default_order_params ( self , order_type , market_index , base_asset_amount , direction ) Source code in driftpy/drift_client.py def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) deposit ( self , amount , spot_market_index , user_token_account , user_id = 0 , reduce_only = False , user_initialized = True ) async deposits collateral into protocol Parameters: Name Type Description Default amount int amount to deposit required spot_market_index int required user_token_account Pubkey required user_id int subaccount to deposit into. Defaults to 0. 0 reduce_only bool paying back borrow vs depositing new assets. Defaults to False. False user_initialized bool if need to initialize user account too set this to False. Defaults to True. True Returns: Type Description str sig Source code in driftpy/drift_client.py async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) from_config ( config , provider , authority = None ) staticmethod Initializes the drift client object from a Config Parameters: Name Type Description Default config Config the config to initialize form required provider Provider anchor provider required authority Keypair description . Defaults to None. None Returns: Type Description DriftClient : the drift client object Source code in driftpy/drift_client.py @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client get_add_insurance_fund_stake_ix ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_add_liquidity_ix ( self , amount , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_order_ix ( self , order_id = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_orders_ix ( self , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) get_close_position_ix ( self , market_index , limit_price = 0 , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix get_deposit_collateral_ix ( self , amount , spot_market_index , user_token_account , user_id = 0 , reduce_only = False , user_initialized = True ) async Source code in driftpy/drift_client.py async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_increase_compute_ix ( self ) Source code in driftpy/drift_client.py def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix get_initialize_insurance_fund_stake_ix ( self , spot_market_index ) Source code in driftpy/drift_client.py def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) get_initialize_user_instructions ( self , user_id = 0 , name = 'Main Account' ) Source code in driftpy/drift_client.py def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix get_initialize_user_stats ( self ) Source code in driftpy/drift_client.py def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) get_liquidate_perp_ix ( self , user_authority , market_index , max_base_asset_amount , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority , perp_market_index , spot_market_index , max_pnl_transfer , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result get_liquidate_spot_ix ( self , user_authority , asset_market_index , liability_market_index , max_liability_transfer , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) get_open_position_ix ( self , direction , amount , market_index , user_id = 0 , limit_price = 0 , ioc = False ) async Source code in driftpy/drift_client.py async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix get_oracle_price_data ( self , oracle ) async Source code in driftpy/drift_client.py async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) get_perp_market ( self , market_index ) async Source code in driftpy/drift_client.py async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) get_place_and_take_ix ( self , order_params , maker_info = None , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_place_perp_order_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix get_place_perp_orders_ix ( self , order_params , user_id = 0 , cancel_all = True ) async Source code in driftpy/drift_client.py async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs get_place_spot_order_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix get_place_spot_orders_ix ( self , order_params , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs get_remaining_accounts ( self , writable_market_index = None , writable_spot_market_index = None , readable_spot_market_index = None , user_id = [ 0 ], include_oracles = True , include_spot_markets = True , authority = None ) async Source code in driftpy/drift_client.py async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts get_remove_insurance_fund_stake_ix ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) get_remove_liquidity_ix ( self , amount , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_request_remove_insurance_fund_stake_ix ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) get_resolve_perp_bankruptcy_ix ( self , user_authority , market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_resolve_spot_bankruptcy_ix ( self , user_authority , spot_market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) get_settle_expired_market_ix ( self , market_index ) async Source code in driftpy/drift_client.py async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_settle_lp_ix ( self , settlee_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) get_settle_pnl_ix ( self , user_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] get_spot_market ( self , market_index ) async Source code in driftpy/drift_client.py async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) get_state ( self ) async Source code in driftpy/drift_client.py async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) get_state_public_key ( self ) Source code in driftpy/drift_client.py def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) get_update_amm_ix ( self , market_indexs ) async Source code in driftpy/drift_client.py async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) get_user ( self , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) get_user_account_public_key ( self , user_id = 0 ) Source code in driftpy/drift_client.py def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) get_user_position ( self , market_index , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position get_user_spot_position ( self , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position get_user_stats_public_key ( self ) Source code in driftpy/drift_client.py def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) get_withdraw_collateral_ix ( self , amount , spot_market_index , user_token_account , reduce_only = False , user_id = 0 ) async Source code in driftpy/drift_client.py async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) initialize_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) intialize_user ( self , user_id = 0 ) async intializes a drift user Parameters: Name Type Description Default user_id int subaccount id to initialize. Defaults to 0. 0 Returns: Type Description str tx signature Source code in driftpy/drift_client.py async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) liquidate_perp ( self , user_authority , market_index , max_base_asset_amount , limit_price = None , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) liquidate_perp_pnl_for_deposit ( self , user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) liquidate_spot ( self , user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) open_position ( self , direction , amount , market_index , user_id = 0 , limit_price = 0 , ioc = False ) async Source code in driftpy/drift_client.py async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) place_and_take ( self , order_params , maker_info = None , subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) place_perp_order ( self , order_params , maker_info = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) place_spot_order ( self , order_params , maker_info = None , user_id = 0 ) async Source code in driftpy/drift_client.py async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) remove_insurance_fund_stake ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) remove_liquidity ( self , amount , market_index , user_id = 0 ) async burns LP tokens and removes liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to burn required market_index int required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) request_remove_insurance_fund_stake ( self , spot_market_index , amount ) async Source code in driftpy/drift_client.py async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) resolve_perp_bankruptcy ( self , user_authority , market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) resolve_spot_bankruptcy ( self , user_authority , spot_market_index , user_subaccount_id = 0 , liq_subaccount_id = 0 ) async Source code in driftpy/drift_client.py async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) send_ixs ( self , ixs , signers = None ) async Source code in driftpy/drift_client.py async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) settle_expired_market ( self , market_index ) async Source code in driftpy/drift_client.py async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) settle_lp ( self , settlee_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) settle_pnl ( self , user_authority , market_index , user_id = 0 ) async Source code in driftpy/drift_client.py async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) settle_revenue_to_insurance_fund ( self , spot_market_index ) async Source code in driftpy/drift_client.py async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), ) update_amm ( self , market_indexs ) async Source code in driftpy/drift_client.py async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) withdraw ( self , amount , spot_market_index , user_token_account , reduce_only = False , user_id = 0 ) async withdraws from drift protocol (can also allow borrowing) Parameters: Name Type Description Default amount int amount to withdraw required spot_market_index int required user_token_account Pubkey ata of the account to withdraw to required reduce_only bool if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. False user_id int subaccount. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] )","title":"Drift Client"},{"location":"clearing_house/#drift-client","text":"This object is used to interact with the protocol (deposit, withdraw, trade, lp, etc.)","title":"Drift Client"},{"location":"clearing_house/#example","text":"drift_client = DriftClient . from_config ( config , provider ) # open a 10 SOL long position sig = await drift_client . open_position ( PositionDirection . LONG (), # long int ( 10 * BASE_PRECISION ), # 10 in base precision 0 , # sol market index ) # mint 100 LP shares on the SOL market await drift_client . add_liquidity ( int ( 100 * AMM_RESERVE_PRECISION ), 0 , )","title":"Example"},{"location":"clearing_house/#driftpy.drift_client","text":"","title":"drift_client"},{"location":"clearing_house/#driftpy.drift_client.DEFAULT_USER_NAME","text":"","title":"DEFAULT_USER_NAME"},{"location":"clearing_house/#driftpy.drift_client.DriftClient","text":"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. Source code in driftpy/drift_client.py class DriftClient : \"\"\"This class is the main way to interact with Drift Protocol including depositing, opening new positions, closing positions, placing orders, etc. \"\"\" def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id ) async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) ) def get_state_public_key ( self ): return get_state_public_key ( self . program_id ) def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority ) async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None ) async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None ) async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None ) async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None ) async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx ) async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs ) def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] ) async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] ) async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] ) async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] ) async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id )) async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), ) async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), ) async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] ) async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] ) async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] ) async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], ) async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), ) async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) ) async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , ) async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) ) async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) ) async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ] async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] ) async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] ) async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), ) async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) ) async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), ) async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) ) async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), ) async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) ) def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), ) async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs )) async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), ) async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), )","title":"DriftClient"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.__init__","text":"Initializes the drift client object -- likely want to use the .from_config method instead of this one Parameters: Name Type Description Default program Program Drift anchor program (see from_config on how to initialize it) required authority Keypair Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. None Source code in driftpy/drift_client.py def __init__ ( self , program : Program , signer : Keypair = None , authority : Pubkey = None , account_subscriber : Optional [ DriftClientAccountSubscriber ] = None , tx_params : Optional [ TxParams ] = None , tx_version : Optional [ TransactionVersion ] = None , ): \"\"\"Initializes the drift client object -- likely want to use the .from_config method instead of this one Args: program (Program): Drift anchor program (see from_config on how to initialize it) authority (Keypair, optional): Authority of all txs - if None will default to the Anchor Provider.Wallet Keypair. \"\"\" self . program = program self . program_id = program . program_id self . user_index = None if signer is None : signer = program . provider . wallet . payer if authority is None : authority = signer . pubkey () self . signer = signer self . authority = authority self . signers = [ self . signer ] self . usdc_ata = None self . spot_market_atas = {} self . subaccounts = [ 0 ] if account_subscriber is None : account_subscriber = CachedDriftClientAccountSubscriber ( self . program ) self . account_subscriber = account_subscriber if tx_params is None : tx_params = TxParams ( 600_000 , 0 ) self . tx_params = tx_params self . tx_version = tx_version if tx_version is not None else Legacy","title":"__init__()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.add_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def add_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_add_insurance_fund_stake_ix ( spot_market_index , amount ) )","title":"add_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.add_liquidity","text":"mint LP tokens and add liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to mint required market_index int market you want to lp in required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def add_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"mint LP tokens and add liquidity to the DAMM Args: amount (int): amount of lp tokens to mint market_index (int): market you want to lp in user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_add_liquidity_ix ( amount , market_index , user_id )] )","title":"add_liquidity()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_order","text":"cancel specific order (if order_id=None will be most recent order) Parameters: Name Type Description Default order_id Optional[int] Defaults to None. None user_id int subaccount id which contains order. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_order ( self , order_id : Optional [ int ] = None , user_id : int = 0 , ): \"\"\"cancel specific order (if order_id=None will be most recent order) Args: order_id (Optional[int], optional): Defaults to None. user_id (int, optional): subaccount id which contains order. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_order_ix ( order_id , user_id ), )","title":"cancel_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_orders","text":"cancel all existing orders on the book Parameters: Name Type Description Default user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def cancel_orders ( self , user_id : int = 0 ): \"\"\"cancel all existing orders on the book Args: user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( await self . get_cancel_orders_ix ( user_id ))","title":"cancel_orders()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.cancel_request_remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def cancel_request_remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_cancel_request_remove_insurance_fund_stake_ix ( spot_market_index ) )","title":"cancel_request_remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.close_position","text":"Source code in driftpy/drift_client.py async def close_position ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): return await self . send_ixs ( await self . get_close_position_ix ( market_index , limit_price , subaccount_id = subaccount_id ) )","title":"close_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.default_order_params","text":"Source code in driftpy/drift_client.py def default_order_params ( self , order_type , market_index , base_asset_amount , direction ) -> OrderParams : return OrderParams ( order_type , market_type = MarketType . PERP (), direction = direction , user_order_id = 0 , base_asset_amount = base_asset_amount , price = 0 , market_index = market_index , reduce_only = False , post_only = PostOnlyParams . NONE (), immediate_or_cancel = False , trigger_price = 0 , trigger_condition = OrderTriggerCondition . ABOVE (), oracle_price_offset = 0 , auction_duration = None , max_ts = None , auction_start_price = None , auction_end_price = None , )","title":"default_order_params()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.deposit","text":"deposits collateral into protocol Parameters: Name Type Description Default amount int amount to deposit required spot_market_index int required user_token_account Pubkey required user_id int subaccount to deposit into. Defaults to 0. 0 reduce_only bool paying back borrow vs depositing new assets. Defaults to False. False user_initialized bool if need to initialize user account too set this to False. Defaults to True. True Returns: Type Description str sig Source code in driftpy/drift_client.py async def deposit ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ): \"\"\"deposits collateral into protocol Args: amount (int): amount to deposit spot_market_index (int): user_token_account (Pubkey): user_id (int, optional): subaccount to deposit into. Defaults to 0. reduce_only (bool, optional): paying back borrow vs depositing new assets. Defaults to False. user_initialized (bool, optional): if need to initialize user account too set this to False. Defaults to True. Returns: str: sig \"\"\" return await self . send_ixs ( [ await self . get_deposit_collateral_ix ( amount , spot_market_index , user_token_account , user_id , reduce_only , user_initialized , ) ] )","title":"deposit()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.from_config","text":"Initializes the drift client object from a Config Parameters: Name Type Description Default config Config the config to initialize form required provider Provider anchor provider required authority Keypair description . Defaults to None. None Returns: Type Description DriftClient : the drift client object Source code in driftpy/drift_client.py @staticmethod def from_config ( config : Config , provider : Provider , authority : Keypair = None ): \"\"\"Initializes the drift client object from a Config Args: config (Config): the config to initialize form provider (Provider): anchor provider authority (Keypair, optional): _description_. Defaults to None. Returns: DriftClient : the drift client object \"\"\" # read the idl file = Path ( str ( driftpy . __path__ [ 0 ]) + \"/idl/drift.json\" ) print ( file ) with file . open () as f : raw = file . read_text () idl = Idl . from_json ( raw ) # create the program program = Program ( idl , config . drift_client_program_id , provider , ) drift_client = DriftClient ( program , authority ) drift_client . config = config drift_client . idl = idl return drift_client","title":"from_config()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_add_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_add_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , ) assert ( self . spot_market_atas [ spot_market_index ] is not None ), \"please set self.spot_market_atas[spot_market_index] as your spot ata pubkey before this ix\" return self . program . instruction [ \"add_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_add_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_add_liquidity_ix","text":"Source code in driftpy/drift_client.py async def get_add_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"add_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_add_liquidity_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_order_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_order_ix ( self , order_id : Optional [ int ] = None , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_order\" ]( order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_cancel_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_orders_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_orders_ix ( self , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( user_id = user_id ) return self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_cancel_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_cancel_request_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_cancel_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index ) return self . program . instruction [ \"cancel_request_remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), )","title":"get_cancel_request_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_close_position_ix","text":"Source code in driftpy/drift_client.py async def get_close_position_ix ( self , market_index : int , limit_price : int = 0 , subaccount_id : int = 0 ): position = await self . get_user_position ( market_index , subaccount_id ) if position is None or position . base_asset_amount == 0 : print ( \"=> user has no position to close...\" ) return order = self . default_order_params ( order_type = OrderType . MARKET (), market_index = market_index , base_asset_amount = abs ( int ( position . base_asset_amount )), direction = PositionDirection . LONG () if position . base_asset_amount < 0 else PositionDirection . SHORT (), ) order . limit_price = limit_price order . reduce_only = True ix = await self . get_place_and_take_ix ( order , subaccount_id = subaccount_id ) return ix","title":"get_close_position_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_deposit_collateral_ix","text":"Source code in driftpy/drift_client.py async def get_deposit_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , user_id : int = 0 , reduce_only = False , user_initialized = True , ) -> Instruction : if user_initialized : remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = user_id ) else : raise Exception ( \"not implemented...\" ) spot_market_pk = get_spot_market_public_key ( self . program_id , spot_market_index ) spot_vault_public_key = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) user_account_public_key = get_user_account_public_key ( self . program_id , self . authority , user_id ) return self . program . instruction [ \"deposit\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market_pk , \"spot_market_vault\" : spot_vault_public_key , \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_deposit_collateral_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_increase_compute_ix","text":"Source code in driftpy/drift_client.py def get_increase_compute_ix ( self ) -> Instruction : program_id = Pubkey ( \"ComputeBudget111111111111111111111111111111\" ) name_bytes = bytearray ( 1 + 4 + 4 ) pack_into ( \"B\" , name_bytes , 0 , 0 ) pack_into ( \"I\" , name_bytes , 1 , 500_000 ) pack_into ( \"I\" , name_bytes , 5 , 0 ) data = bytes ( name_bytes ) compute_ix = Instruction ( program_id , data , []) return compute_ix","title":"get_increase_compute_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py def get_initialize_insurance_fund_stake_ix ( self , spot_market_index : int , ): return self . program . instruction [ \"initialize_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"state\" : get_state_public_key ( self . program_id ), \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , } ), )","title":"get_initialize_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_user_instructions","text":"Source code in driftpy/drift_client.py def get_initialize_user_instructions ( self , user_id : int = 0 , name : str = DEFAULT_USER_NAME ) -> Instruction : user_public_key = self . get_user_account_public_key ( user_id ) state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () if len ( name ) > 32 : raise Exception ( \"name too long\" ) name_bytes = bytearray ( 32 ) pack_into ( f \" { len ( name ) } s\" , name_bytes , 0 , name . encode ( \"utf-8\" )) offset = len ( name ) for _ in range ( 32 - len ( name )): pack_into ( \"1s\" , name_bytes , offset , \" \" . encode ( \"utf-8\" )) offset += 1 str_name_bytes = name_bytes . hex () name_byte_array = [] for i in range ( 0 , len ( str_name_bytes ), 2 ): name_byte_array . append ( int ( str_name_bytes [ i : i + 2 ], 16 )) initialize_user_account_ix = self . program . instruction [ \"initialize_user\" ]( user_id , name_byte_array , ctx = Context ( accounts = { \"user\" : user_public_key , \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), ) return initialize_user_account_ix","title":"get_initialize_user_instructions()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_initialize_user_stats","text":"Source code in driftpy/drift_client.py def get_initialize_user_stats ( self , ): state_public_key = self . get_state_public_key () user_stats_public_key = self . get_user_stats_public_key () return self . program . instruction [ \"initialize_user_stats\" ]( ctx = Context ( accounts = { \"user_stats\" : user_stats_public_key , \"state\" : state_public_key , \"authority\" : self . authority , \"payer\" : self . authority , \"rent\" : RENT , \"system_program\" : ID , }, ), )","title":"get_initialize_user_stats()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_perp_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_perp_ix ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_perp\" ]( market_index , max_base_asset_amount , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), )","title":"get_liquidate_perp_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_perp_pnl_for_deposit_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_perp_pnl_for_deposit_ix ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = perp_market_index , writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) result = self . program . instruction [ \"liquidate_perp_pnl_for_deposit\" ]( perp_market_index , spot_market_index , max_pnl_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), ) return result","title":"get_liquidate_perp_pnl_for_deposit_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_liquidate_spot_ix","text":"Source code in driftpy/drift_client.py async def get_liquidate_spot_ix ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , limit_price : int = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_id = user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = [ liability_market_index , asset_market_index ], authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) return self . program . instruction [ \"liquidate_spot\" ]( asset_market_index , liability_market_index , max_liability_transfer , limit_price , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , }, remaining_accounts = remaining_accounts , ), )","title":"get_liquidate_spot_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_open_position_ix","text":"Source code in driftpy/drift_client.py async def get_open_position_ix ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): order = self . default_order_params ( order_type = OrderType . MARKET (), direction = direction , market_index = market_index , base_asset_amount = amount , ) order . limit_price = limit_price ix = await self . get_place_and_take_ix ( order , subaccount_id = user_id ) return ix","title":"get_open_position_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_oracle_price_data","text":"Source code in driftpy/drift_client.py async def get_oracle_price_data ( self , oracle : Pubkey ) -> Optional [ OraclePriceData ]: oracle_price_data_and_slot = ( await self . account_subscriber . get_oracle_data_and_slot ( oracle ) ) return getattr ( oracle_price_data_and_slot , \"data\" , None )","title":"get_oracle_price_data()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_perp_market","text":"Source code in driftpy/drift_client.py async def get_perp_market ( self , market_index : int ) -> Optional [ PerpMarket ]: perp_market_and_slot = await self . account_subscriber . get_perp_market_and_slot ( market_index ) return getattr ( perp_market_and_slot , \"data\" , None )","title":"get_perp_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_and_take_ix","text":"Source code in driftpy/drift_client.py async def get_place_and_take_ix ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( subaccount_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = subaccount_id , ) maker_order_id = None if maker_info is not None : maker_order_id = maker_info . order . order_id remaining_accounts . append ( AccountMeta ( pubkey = maker_info . maker , is_signer = False , is_writable = True ) ) return self . program . instruction [ \"place_and_take_perp_order\" ]( order_params , maker_order_id , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"user_stats\" : self . get_user_stats_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_place_and_take_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_perp_order_ix","text":"Source code in driftpy/drift_client.py async def get_place_perp_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params . market_index , user_id = user_id ) ix = self . program . instruction [ \"place_perp_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix","title":"get_place_perp_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_perp_orders_ix","text":"Source code in driftpy/drift_client.py async def get_place_perp_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , cancel_all = True ): user_account_public_key = self . get_user_account_public_key ( user_id ) writeable_market_indexes = list ( set ([ x . market_index for x in order_params ])) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = writeable_market_indexes , user_id = user_id ) ixs = [] if cancel_all : ixs . append ( self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), )) for order_param in order_params : ix = self . program . instruction [ \"place_perp_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs","title":"get_place_perp_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_spot_order_ix","text":"Source code in driftpy/drift_client.py async def get_place_spot_order_ix ( self , order_params : OrderParams , user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( readable_spot_market_index = [ 0 , order_params . market_index ], user_id = user_id ) ix = self . program . instruction [ \"place_spot_order\" ]( order_params , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) return ix","title":"get_place_spot_order_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_place_spot_orders_ix","text":"Source code in driftpy/drift_client.py async def get_place_spot_orders_ix ( self , order_params : List [ OrderParams ], user_id : int = 0 , ): user_account_public_key = self . get_user_account_public_key ( user_id ) remaining_accounts = await self . get_remaining_accounts ( writable_market_index = order_params [ 0 ] . market_index , user_id = user_id ) ixs = [ self . program . instruction [ \"cancel_orders\" ]( None , None , None , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : self . get_user_account_public_key ( user_id ), \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ] for order_param in order_params : ix = self . program . instruction [ \"place_spot_order\" ]( order_param , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : user_account_public_key , \"authority\" : self . signer . pubkey (), }, remaining_accounts = remaining_accounts , ), ) ixs . append ( ix ) return ixs","title":"get_place_spot_orders_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remaining_accounts","text":"Source code in driftpy/drift_client.py async def get_remaining_accounts ( self , writable_market_index : int = None , writable_spot_market_index : int = None , readable_spot_market_index : int = None , user_id = [ 0 ], include_oracles : bool = True , include_spot_markets : bool = True , authority : Optional [ Union [ Pubkey , Sequence [ Pubkey ]]] = None , ): if authority is None : authority = [ self . authority ] elif isinstance ( authority , Pubkey ): authority = [ authority ] if isinstance ( user_id , int ): user_id = [ user_id ] assert len ( user_id ) == len ( authority ) or len ( user_id ) == 0 accounts = [] for pk , id in zip ( authority , user_id ): user_public_key = get_user_account_public_key ( self . program . program_id , pk , id ) user_account = await get_user_account ( self . program , user_public_key ) accounts . append ( user_account ) oracle_map = {} spot_market_map = {} market_map = {} async def track_market ( market_index , is_writable ): perp_market = await self . get_perp_market ( market_index ) market_map [ market_index ] = AccountMeta ( pubkey = perp_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles : spot_market = await self . get_spot_market ( perp_market . quote_spot_market_index ) if spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . oracle )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) oracle_map [ str ( perp_market . pubkey )] = AccountMeta ( pubkey = perp_market . amm . oracle , is_signer = False , is_writable = False ) async def track_spot_market ( spot_market_index , is_writable ): spot_market = await self . get_spot_market ( spot_market_index ) spot_market_map [ spot_market_index ] = AccountMeta ( pubkey = spot_market . pubkey , is_signer = False , is_writable = is_writable , ) if include_oracles and spot_market . oracle != Pubkey . default (): oracle_map [ str ( spot_market . pubkey )] = AccountMeta ( pubkey = spot_market . oracle , is_signer = False , is_writable = False ) for user_account in accounts : for position in user_account . perp_positions : if not is_available ( position ): market_index = position . market_index await track_market ( market_index , is_writable = True ) if include_spot_markets : for spot_market_balance in user_account . spot_positions : if not is_spot_position_available ( spot_market_balance ): await track_spot_market ( spot_market_balance . market_index , is_writable = False ) if readable_spot_market_index is not None : if isinstance ( readable_spot_market_index , int ): readable_spot_market_index = [ readable_spot_market_index ] for i in readable_spot_market_index : await track_spot_market ( i , is_writable = False ) if writable_market_index is not None : if isinstance ( writable_market_index , int ): writable_market_index = [ writable_market_index ] for i in writable_market_index : await track_market ( i , is_writable = True ) if writable_spot_market_index is not None and include_spot_markets : if isinstance ( writable_spot_market_index , int ): writable_spot_market_index = [ writable_spot_market_index ] for i in writable_spot_market_index : await track_spot_market ( i , is_writable = True ) remaining_accounts = [ * oracle_map . values (), * spot_market_map . values (), * market_map . values (), ] return remaining_accounts","title":"get_remaining_accounts()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_remove_insurance_fund_stake_ix ( self , spot_market_index : int ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"remove_insurance_fund_stake\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"user_token_account\" : self . spot_market_atas [ spot_market_index ], \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = ra , ), )","title":"get_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_remove_liquidity_ix","text":"Source code in driftpy/drift_client.py async def get_remove_liquidity_ix ( self , amount : int , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , user_id = user_id ) user_account_public_key = self . get_user_account_public_key ( user_id ) return self . program . instruction [ \"remove_perp_lp_shares\" ]( amount , market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"user\" : user_account_public_key , \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_remove_liquidity_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_request_remove_insurance_fund_stake_ix","text":"Source code in driftpy/drift_client.py async def get_request_remove_insurance_fund_stake_ix ( self , spot_market_index : int , amount : int , ): ra = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , user_id = [], # dont need the user account (might not exist) ) return self . program . instruction [ \"request_remove_insurance_fund_stake\" ]( spot_market_index , amount , ctx = Context ( accounts = { \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"insurance_fund_stake\" : get_insurance_fund_stake_public_key ( self . program_id , self . authority , spot_market_index ), \"user_stats\" : get_user_stats_account_public_key ( self . program_id , self . authority ), \"authority\" : self . authority , \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ), }, remaining_accounts = ra , ), )","title":"get_request_remove_insurance_fund_stake_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_resolve_perp_bankruptcy_ix","text":"Source code in driftpy/drift_client.py async def get_resolve_perp_bankruptcy_ix ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_perp_bankruptcy\" ]( QUOTE_ASSET_BANK_INDEX , market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_resolve_perp_bankruptcy_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_resolve_spot_bankruptcy_ix","text":"Source code in driftpy/drift_client.py async def get_resolve_spot_bankruptcy_ix ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): user_pk = get_user_account_public_key ( self . program_id , user_authority , user_subaccount_id ) user_stats_pk = get_user_stats_account_public_key ( self . program_id , user_authority , ) liq_pk = self . get_user_account_public_key ( liq_subaccount_id ) liq_stats_pk = self . get_user_stats_public_key () remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , authority = [ user_authority , self . authority ], user_id = [ user_subaccount_id , liq_subaccount_id ], ) if_vault = get_insurance_fund_vault_public_key ( self . program_id , spot_market_index ) spot_vault = get_spot_market_vault_public_key ( self . program_id , spot_market_index ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"resolve_spot_bankruptcy\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : user_pk , \"user_stats\" : user_stats_pk , \"liquidator\" : liq_pk , \"liquidator_stats\" : liq_stats_pk , \"spot_market_vault\" : spot_vault , \"insurance_fund_vault\" : if_vault , \"drift_signer\" : dc_signer , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_resolve_spot_bankruptcy_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_expired_market_ix","text":"Source code in driftpy/drift_client.py async def get_settle_expired_market_ix ( self , market_index : int , ): market = await get_perp_market_account ( self . program , market_index ) market_account_infos = [ AccountMeta ( pubkey = market . pubkey , is_writable = True , is_signer = False , ) ] oracle_account_infos = [ AccountMeta ( pubkey = market . amm . oracle , is_writable = False , is_signer = False , ) ] spot_pk = get_spot_market_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ) spot_account_infos = [ AccountMeta ( pubkey = spot_pk , is_writable = True , is_signer = False , ) ] remaining_accounts = ( oracle_account_infos + spot_account_infos + market_account_infos ) return self . program . instruction [ \"settle_expired_market\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_settle_expired_market_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_lp_ix","text":"Source code in driftpy/drift_client.py async def get_settle_lp_ix ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 ): remaining_accounts = await self . get_remaining_accounts ( writable_market_index = market_index , authority = settlee_authority , user_id = user_id , ) return self . program . instruction [ \"settle_lp\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"user\" : get_user_account_public_key ( self . program_id , settlee_authority , user_id ), }, remaining_accounts = remaining_accounts , ), )","title":"get_settle_lp_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_settle_pnl_ix","text":"Source code in driftpy/drift_client.py async def get_settle_pnl_ix ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): remaining_accounts = await self . get_remaining_accounts ( authority = user_authority , writable_market_index = market_index , writable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) return [ self . get_increase_compute_ix (), self . program . instruction [ \"settle_pnl\" ]( market_index , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , \"user\" : get_user_account_public_key ( self . program_id , user_authority , user_id ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , QUOTE_ASSET_BANK_INDEX ), }, remaining_accounts = remaining_accounts , ), ), ]","title":"get_settle_pnl_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_spot_market","text":"Source code in driftpy/drift_client.py async def get_spot_market ( self , market_index : int ) -> Optional [ SpotMarket ]: spot_market_and_slot = await self . account_subscriber . get_spot_market_and_slot ( market_index ) return getattr ( spot_market_and_slot , \"data\" , None )","title":"get_spot_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_state","text":"Source code in driftpy/drift_client.py async def get_state ( self ) -> Optional [ State ]: state_and_slot = await self . account_subscriber . get_state_account_and_slot () return getattr ( state_and_slot , \"data\" , None )","title":"get_state()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_state_public_key","text":"Source code in driftpy/drift_client.py def get_state_public_key ( self ): return get_state_public_key ( self . program_id )","title":"get_state_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_update_amm_ix","text":"Source code in driftpy/drift_client.py async def get_update_amm_ix ( self , market_indexs : list [ int ], ): n = len ( market_indexs ) for _ in range ( 5 - n ): market_indexs . append ( 100 ) market_infos = [] oracle_infos = [] for idx in market_indexs : if idx != 100 : market = await get_perp_market_account ( self . program , idx ) market_infos . append ( AccountMeta ( pubkey = market . pubkey , is_signer = False , is_writable = True , ) ) oracle_infos . append ( AccountMeta ( pubkey = market . amm . oracle , is_signer = False , is_writable = False ) ) remaining_accounts = oracle_infos + market_infos return self . program . instruction [ \"update_amms\" ]( market_indexs , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"authority\" : self . authority , }, remaining_accounts = remaining_accounts , ), )","title":"get_update_amm_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user","text":"Source code in driftpy/drift_client.py async def get_user ( self , user_id = 0 ) -> User : return await get_user_account ( self . program , self . get_user_account_public_key ( user_id ) )","title":"get_user()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_account_public_key","text":"Source code in driftpy/drift_client.py def get_user_account_public_key ( self , user_id = 0 ) -> Pubkey : return get_user_account_public_key ( self . program_id , self . authority , user_id )","title":"get_user_account_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_position","text":"Source code in driftpy/drift_client.py async def get_user_position ( self , market_index : int , subaccount_id : int = 0 , ) -> Optional [ PerpPosition ]: user = await self . get_user ( subaccount_id ) found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position","title":"get_user_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_spot_position","text":"Source code in driftpy/drift_client.py async def get_user_spot_position ( self , market_index : int , user_id : int = 0 , ) -> Optional [ SpotPosition ]: user = await get_user_account ( self . program , self . authority , user_id ) found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"get_user_spot_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_user_stats_public_key","text":"Source code in driftpy/drift_client.py def get_user_stats_public_key ( self ): return get_user_stats_account_public_key ( self . program_id , self . authority )","title":"get_user_stats_public_key()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.get_withdraw_collateral_ix","text":"Source code in driftpy/drift_client.py async def get_withdraw_collateral_ix ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): spot_market = await self . get_spot_market ( spot_market_index ) remaining_accounts = await self . get_remaining_accounts ( writable_spot_market_index = spot_market_index , readable_spot_market_index = QUOTE_ASSET_BANK_INDEX , user_id = user_id , ) dc_signer = get_drift_client_signer_public_key ( self . program_id ) return self . program . instruction [ \"withdraw\" ]( spot_market_index , amount , reduce_only , ctx = Context ( accounts = { \"state\" : self . get_state_public_key (), \"spot_market\" : spot_market . pubkey , \"spot_market_vault\" : spot_market . vault , \"drift_signer\" : dc_signer , \"user\" : self . get_user_account_public_key ( user_id ), \"user_stats\" : self . get_user_stats_public_key (), \"user_token_account\" : user_token_account , \"authority\" : self . authority , \"token_program\" : TOKEN_PROGRAM_ID , }, remaining_accounts = remaining_accounts , ), )","title":"get_withdraw_collateral_ix()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.initialize_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def initialize_insurance_fund_stake ( self , spot_market_index : int , ): return await self . send_ixs ( self . get_initialize_insurance_fund_stake_ix ( spot_market_index ) )","title":"initialize_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.intialize_user","text":"intializes a drift user Parameters: Name Type Description Default user_id int subaccount id to initialize. Defaults to 0. 0 Returns: Type Description str tx signature Source code in driftpy/drift_client.py async def intialize_user ( self , user_id : int = 0 ): \"\"\"intializes a drift user Args: user_id (int, optional): subaccount id to initialize. Defaults to 0. Returns: str: tx signature \"\"\" ixs = [] if user_id == 0 : ixs . append ( self . get_initialize_user_stats ()) ix = self . get_initialize_user_instructions ( user_id ) ixs . append ( ix ) return await self . send_ixs ( ixs )","title":"intialize_user()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_perp","text":"Source code in driftpy/drift_client.py async def liquidate_perp ( self , user_authority : Pubkey , market_index : int , max_base_asset_amount : int , limit_price : Optional [ int ] = None , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_perp_ix ( user_authority , market_index , max_base_asset_amount , limit_price , user_subaccount_id , liq_subaccount_id , ) ] )","title":"liquidate_perp()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_perp_pnl_for_deposit","text":"Source code in driftpy/drift_client.py async def liquidate_perp_pnl_for_deposit ( self , user_authority : Pubkey , perp_market_index : int , spot_market_index : int , max_pnl_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( self . get_liquidate_perp_pnl_for_deposit_ix ( user_authority , perp_market_index , spot_market_index , max_pnl_transfer , user_subaccount_id , liq_subaccount_id , ) )","title":"liquidate_perp_pnl_for_deposit()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.liquidate_spot","text":"Source code in driftpy/drift_client.py async def liquidate_spot ( self , user_authority : Pubkey , asset_market_index : int , liability_market_index : int , max_liability_transfer : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_liquidate_spot_ix ( user_authority , asset_market_index , liability_market_index , max_liability_transfer , user_subaccount_id , liq_subaccount_id , ) ] )","title":"liquidate_spot()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.open_position","text":"Source code in driftpy/drift_client.py async def open_position ( self , direction : PositionDirection , amount : int , market_index : int , user_id : int = 0 , limit_price : int = 0 , ioc : bool = False , ): return await self . send_ixs ( await self . get_open_position_ix ( direction , amount , market_index , user_id , limit_price , ioc , ), )","title":"open_position()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_and_take","text":"Source code in driftpy/drift_client.py async def place_and_take ( self , order_params : OrderParams , maker_info : MakerInfo = None , subaccount_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_and_take_ix ( order_params , maker_info , subaccount_id ), ] )","title":"place_and_take()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_perp_order","text":"Source code in driftpy/drift_client.py async def place_perp_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), ( await self . get_place_perp_order_ix ( order_params , user_id ))[ - 1 ] ] )","title":"place_perp_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.place_spot_order","text":"Source code in driftpy/drift_client.py async def place_spot_order ( self , order_params : OrderParams , maker_info : MakerInfo = None , user_id : int = 0 , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_place_spot_order_ix ( order_params , user_id ), ] )","title":"place_spot_order()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def remove_insurance_fund_stake ( self , spot_market_index : int ): return await self . send_ixs ( await self . get_remove_insurance_fund_stake_ix ( spot_market_index ) )","title":"remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.remove_liquidity","text":"burns LP tokens and removes liquidity to the DAMM Parameters: Name Type Description Default amount int amount of lp tokens to burn required market_index int required user_id int subaccount id. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def remove_liquidity ( self , amount : int , market_index : int , user_id : int = 0 ): \"\"\"burns LP tokens and removes liquidity to the DAMM Args: amount (int): amount of lp tokens to burn market_index (int): user_id (int, optional): subaccount id. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_remove_liquidity_ix ( amount , market_index , user_id )] )","title":"remove_liquidity()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.request_remove_insurance_fund_stake","text":"Source code in driftpy/drift_client.py async def request_remove_insurance_fund_stake ( self , spot_market_index : int , amount : int ): return await self . send_ixs ( await self . get_request_remove_insurance_fund_stake_ix ( spot_market_index , amount ) )","title":"request_remove_insurance_fund_stake()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.resolve_perp_bankruptcy","text":"Source code in driftpy/drift_client.py async def resolve_perp_bankruptcy ( self , user_authority : Pubkey , market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_perp_bankruptcy_ix ( user_authority , market_index , user_subaccount_id , liq_subaccount_id , ) ] )","title":"resolve_perp_bankruptcy()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.resolve_spot_bankruptcy","text":"Source code in driftpy/drift_client.py async def resolve_spot_bankruptcy ( self , user_authority : Pubkey , spot_market_index : int , user_subaccount_id : int = 0 , liq_subaccount_id : int = 0 , ): return await self . send_ixs ( [ await self . get_resolve_spot_bankruptcy_ix ( user_authority , spot_market_index , user_subaccount_id , liq_subaccount_id , ) ] )","title":"resolve_spot_bankruptcy()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.send_ixs","text":"Source code in driftpy/drift_client.py async def send_ixs ( self , ixs : Union [ Instruction , list [ Instruction ]], signers = None , ): if isinstance ( ixs , Instruction ): ixs = [ ixs ] if self . tx_params . compute_units is not None : ixs . insert ( 0 , set_compute_unit_limit ( self . tx_params . compute_units )) if self . tx_params . compute_units_price is not None : ixs . insert ( 1 , set_compute_unit_price ( self . tx_params . compute_units_price )) latest_blockhash = ( await self . program . provider . connection . get_latest_blockhash () ) . value . blockhash if self . tx_version == Legacy : tx = Transaction ( instructions = ixs , recent_blockhash = latest_blockhash , fee_payer = self . signer . pubkey (), ) tx . sign_partial ( self . signer ) if signers is not None : [ tx . sign_partial ( signer ) for signer in signers ] elif self . tx_version == 0 : msg = MessageV0 . try_compile ( self . signer . pubkey (), ixs , [], latest_blockhash ) tx = VersionedTransaction ( msg , [ self . signer ]) else : raise NotImplementedError ( \"unknown tx version\" , self . tx_version ) return await self . program . provider . send ( tx )","title":"send_ixs()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_expired_market","text":"Source code in driftpy/drift_client.py async def settle_expired_market ( self , market_index : int , ): return await self . send_ixs ( [ self . get_increase_compute_ix (), await self . get_settle_expired_market_ix ( market_index , ), ] )","title":"settle_expired_market()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_lp","text":"Source code in driftpy/drift_client.py async def settle_lp ( self , settlee_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( [ await self . get_settle_lp_ix ( settlee_authority , market_index , user_id )], signers = [], )","title":"settle_lp()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_pnl","text":"Source code in driftpy/drift_client.py async def settle_pnl ( self , user_authority : Pubkey , market_index : int , user_id : int = 0 , ): return await self . send_ixs ( await self . get_settle_pnl_ix ( user_authority , market_index , user_id ) )","title":"settle_pnl()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.settle_revenue_to_insurance_fund","text":"Source code in driftpy/drift_client.py async def settle_revenue_to_insurance_fund ( self , spot_market_index : int ): return await self . program . rpc [ \"settle_revenue_to_insurance_fund\" ]( spot_market_index , ctx = Context ( accounts = { \"state\" : get_state_public_key ( self . program_id ), \"spot_market\" : get_spot_market_public_key ( self . program_id , spot_market_index ), \"spot_market_vault\" : get_spot_market_vault_public_key ( self . program_id , spot_market_index ), \"drift_signer\" : get_drift_client_signer_public_key ( self . program_id ), \"insurance_fund_vault\" : get_insurance_fund_vault_public_key ( self . program_id , spot_market_index , ), \"token_program\" : TOKEN_PROGRAM_ID , } ), )","title":"settle_revenue_to_insurance_fund()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.update_amm","text":"Source code in driftpy/drift_client.py async def update_amm ( self , market_indexs : list [ int ]): return await self . send_ixs ( await self . get_update_amm_ix ( market_indexs ))","title":"update_amm()"},{"location":"clearing_house/#driftpy.drift_client.DriftClient.withdraw","text":"withdraws from drift protocol (can also allow borrowing) Parameters: Name Type Description Default amount int amount to withdraw required spot_market_index int required user_token_account Pubkey ata of the account to withdraw to required reduce_only bool if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. False user_id int subaccount. Defaults to 0. 0 Returns: Type Description str tx sig Source code in driftpy/drift_client.py async def withdraw ( self , amount : int , spot_market_index : int , user_token_account : Pubkey , reduce_only : bool = False , user_id : int = 0 , ): \"\"\"withdraws from drift protocol (can also allow borrowing) Args: amount (int): amount to withdraw spot_market_index (int): user_token_account (Pubkey): ata of the account to withdraw to reduce_only (bool, optional): if True will only withdraw existing funds else if False will allow taking out borrows. Defaults to False. user_id (int, optional): subaccount. Defaults to 0. Returns: str: tx sig \"\"\" return await self . send_ixs ( [ await self . get_withdraw_collateral_ix ( amount , spot_market_index , user_token_account , reduce_only , user_id ) ] )","title":"withdraw()"},{"location":"clearing_house_user/","text":"User This object is used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.) Example drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl ) drift_user DriftUser This class is the main way to retrieve and inspect drift user account data. Source code in driftpy/drift_user.py class DriftUser : \"\"\"This class is the main way to retrieve and inspect drift user account data.\"\"\" def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) async def get_state ( self ) -> State : return await self . drift_client . get_state () async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price __init__ ( self , drift_client , authority = None , subaccount_id = 0 , account_subscriber = None ) special Initialize the user object Parameters: Name Type Description Default drift_client(DriftClient) required for program_id, idl, things (keypair doesnt matter) required authority Optional[Pubkey] authority to investigate if None will use drift_client.authority None subaccount_id int subaccount of authority to investigate. Defaults to 0. 0 Source code in driftpy/drift_user.py def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber can_be_liquidated ( self ) async Source code in driftpy/drift_user.py async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req get_free_collateral ( self ) async Source code in driftpy/drift_user.py async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral get_leverage ( self , margin_category = None ) async Source code in driftpy/drift_user.py async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage get_margin_requirement ( self , margin_category , liquidation_buffer = 0 , include_open_orders = True , include_spot = True ) async Source code in driftpy/drift_user.py async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result get_open_orders ( self ) async Source code in driftpy/drift_user.py async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders get_perp_liq_price ( self , perp_market_index ) async Source code in driftpy/drift_user.py async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price get_perp_market ( self , market_index ) async Source code in driftpy/drift_user.py async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) get_perp_oracle_data ( self , perp_market ) async Source code in driftpy/drift_user.py async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) get_spot_liq_price ( self , spot_market_index ) async Source code in driftpy/drift_user.py async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price get_spot_market ( self , market_index ) async Source code in driftpy/drift_user.py async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) get_spot_market_asset_value ( self , margin_category = None , include_open_orders = True , market_index = None ) async Source code in driftpy/drift_user.py async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None ) async Source code in driftpy/drift_user.py async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability get_spot_oracle_data ( self , spot_market ) async Source code in driftpy/drift_user.py async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) get_state ( self ) async Source code in driftpy/drift_user.py async def get_state ( self ) -> State : return await self . drift_client . get_state () get_total_collateral ( self , margin_category = None ) async Source code in driftpy/drift_user.py async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral get_total_perp_liability ( self , margin_category = None , liquidation_buffer = 0 , include_open_orders = False ) async Source code in driftpy/drift_user.py async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl get_unrealized_pnl ( self , with_funding = False , market_index = None , with_weight_margin_category = None ) async Source code in driftpy/drift_user.py async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl get_user ( self ) async Source code in driftpy/drift_user.py async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data get_user_position ( self , market_index ) async Source code in driftpy/drift_user.py async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position get_user_spot_position ( self , market_index ) async Source code in driftpy/drift_user.py async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"User"},{"location":"clearing_house_user/#user","text":"This object is used to fetch data from the protocol and view user metrics (leverage, free collateral, etc.)","title":"User"},{"location":"clearing_house_user/#example","text":"drift_client = DriftClient . from_config ( config , provider ) drift_user = User ( drift_client ) # inspect user's leverage leverage = await drift_user . get_leverage () print ( 'current leverage:' , leverage / 10_000 ) # you can also inspect other accounts information using the (authority=) flag bigz_acc = User ( drift_client , authority = PublicKey ( 'bigZ' )) leverage = await bigz_acc . get_leverage () print ( 'bigZs leverage:' , leverage / 10_000 ) # user calls can be expensive on the rpc so we can cache them drift_user = User ( drift_client , use_cache = True ) await drift_user . set_cache () # works without any rpc calls (uses the cached data) upnl = await drift_user . get_unrealized_pnl ( with_funding = True ) print ( 'upnl:' , upnl )","title":"Example"},{"location":"clearing_house_user/#driftpy.drift_user","text":"","title":"drift_user"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser","text":"This class is the main way to retrieve and inspect drift user account data. Source code in driftpy/drift_user.py class DriftUser : \"\"\"This class is the main way to retrieve and inspect drift user account data.\"\"\" def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle ) async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle ) async def get_state ( self ) -> State : return await self . drift_client . get_state () async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index ) async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index ) async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price","title":"DriftUser"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.__init__","text":"Initialize the user object Parameters: Name Type Description Default drift_client(DriftClient) required for program_id, idl, things (keypair doesnt matter) required authority Optional[Pubkey] authority to investigate if None will use drift_client.authority None subaccount_id int subaccount of authority to investigate. Defaults to 0. 0 Source code in driftpy/drift_user.py def __init__ ( self , drift_client : DriftClient , authority : Optional [ Pubkey ] = None , subaccount_id : int = 0 , account_subscriber : Optional [ UserAccountSubscriber ] = None , ): \"\"\"Initialize the user object Args: drift_client(DriftClient): required for program_id, idl, things (keypair doesnt matter) authority (Optional[Pubkey], optional): authority to investigate if None will use drift_client.authority subaccount_id (int, optional): subaccount of authority to investigate. Defaults to 0. \"\"\" self . drift_client = drift_client self . authority = authority if self . authority is None : self . authority = drift_client . authority self . program = drift_client . program self . oracle_program = drift_client self . connection = self . program . provider . connection self . subaccount_id = subaccount_id self . user_public_key = get_user_account_public_key ( self . program . program_id , self . authority , self . subaccount_id ) if account_subscriber is None : account_subscriber = CachedUserAccountSubscriber ( self . user_public_key , self . program ) self . account_subscriber = account_subscriber","title":"__init__()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.can_be_liquidated","text":"Source code in driftpy/drift_user.py async def can_be_liquidated ( self ) -> bool : total_collateral = await self . get_total_collateral () user = await self . get_user () liquidation_buffer = None if user . being_liquidated : liquidation_buffer = ( await self . get_state () ) . liquidation_margin_buffer_ratio maintenance_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , liquidation_buffer ) return total_collateral < maintenance_req","title":"can_be_liquidated()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_free_collateral","text":"Source code in driftpy/drift_user.py async def get_free_collateral ( self ): total_collateral = await self . get_total_collateral () init_margin_req = await self . get_margin_requirement ( MarginCategory . INITIAL , ) free_collateral = total_collateral - init_margin_req free_collateral = max ( 0 , free_collateral ) return free_collateral","title":"get_free_collateral()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_leverage","text":"Source code in driftpy/drift_user.py async def get_leverage ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : total_liability = await self . get_margin_requirement ( margin_category , None ) total_asset_value = await self . get_total_collateral ( margin_category ) if total_asset_value == 0 or total_liability == 0 : return 0 leverage = total_liability * 10_000 / total_asset_value return leverage","title":"get_leverage()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_margin_requirement","text":"Source code in driftpy/drift_user.py async def get_margin_requirement ( self , margin_category : MarginCategory , liquidation_buffer : Optional [ int ] = 0 , include_open_orders = True , include_spot = True , ) -> int : perp_liability = await self . get_total_perp_liability ( margin_category , liquidation_buffer , include_open_orders ) result = perp_liability if include_spot : spot_liability = await self . get_spot_market_liability ( None , margin_category , liquidation_buffer , include_open_orders ) result += spot_liability return result","title":"get_margin_requirement()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_open_orders","text":"Source code in driftpy/drift_user.py async def get_open_orders ( self , # market_type: MarketType, # market_index: int, # position_direction: PositionDirection ): user : User = await self . get_user () return user . orders","title":"get_open_orders()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_liq_price","text":"Source code in driftpy/drift_user.py async def get_perp_liq_price ( self , perp_market_index : int , ) -> Optional [ int ]: position = await self . get_user_position ( perp_market_index ) if position is None or position . base_asset_amount == 0 : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE ) delta_liq = total_collateral - margin_req perp_market = await self . get_perp_market ( perp_market_index ) delta_per_baa = delta_liq / ( position . base_asset_amount / AMM_RESERVE_PRECISION ) oracle_price = ( await self . get_perp_oracle_data ( perp_market ) ) . price / PRICE_PRECISION liq_price = oracle_price - ( delta_per_baa / QUOTE_PRECISION ) if liq_price < 0 : return None return liq_price","title":"get_perp_liq_price()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_market","text":"Source code in driftpy/drift_user.py async def get_perp_market ( self , market_index : int ) -> PerpMarket : return await self . drift_client . get_perp_market ( market_index )","title":"get_perp_market()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_perp_oracle_data","text":"Source code in driftpy/drift_user.py async def get_perp_oracle_data ( self , perp_market : PerpMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( perp_market . amm . oracle )","title":"get_perp_oracle_data()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_liq_price","text":"Source code in driftpy/drift_user.py async def get_spot_liq_price ( self , spot_market_index : int , ) -> Optional [ int ]: position = await self . get_user_spot_position ( spot_market_index ) if position is None : return None total_collateral = await self . get_total_collateral ( MarginCategory . MAINTENANCE ) margin_req = await self . get_margin_requirement ( MarginCategory . MAINTENANCE , None , True , False ) delta_liq = total_collateral - margin_req spot_market = await self . get_spot_market ( spot_market_index ) token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) token_amount_qp = token_amount * QUOTE_PRECISION / ( 10 ** spot_market . decimals ) if abs ( token_amount_qp ) == 0 : return None match str ( position . balance_type ): case \"SpotBalanceType.Borrow()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_liability_weight ) case \"SpotBalanceType.Deposit()\" : liq_price_delta = ( delta_liq * PRICE_PRECISION * SPOT_WEIGHT_PRECISION / token_amount_qp / spot_market . maintenance_asset_weight * - 1 ) case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) price = ( await self . get_spot_oracle_data ( spot_market )) . price liq_price = price + liq_price_delta liq_price /= PRICE_PRECISION if liq_price < 0 : return None return liq_price","title":"get_spot_liq_price()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market","text":"Source code in driftpy/drift_user.py async def get_spot_market ( self , market_index : int ) -> SpotMarket : return await self . drift_client . get_spot_market ( market_index )","title":"get_spot_market()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market_asset_value","text":"Source code in driftpy/drift_user.py async def get_spot_market_asset_value ( self , margin_category : Optional [ MarginCategory ] = None , include_open_orders = True , market_index : Optional [ int ] = None , ): user = await self . get_user () total_value = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : spot_token_value = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) spot_token_value = get_spot_asset_value ( token_amount , oracle_data , spot_market , margin_category ) match str ( position . balance_type ): case \"SpotBalanceType.Deposit()\" : spot_token_value *= 1 case \"SpotBalanceType.Borrow()\" : spot_token_value *= - 1 case _ : raise Exception ( f \"Invalid balance type: { position . balance_type } \" ) total_value += spot_token_value continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount > 0 : baa_value = get_spot_asset_value ( worst_case_token_amount , oracle_data , spot_market , margin_category ) total_value += baa_value if worst_case_quote_amount > 0 : total_value += worst_case_quote_amount return total_value","title":"get_spot_market_asset_value()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_market_liability","text":"Source code in driftpy/drift_user.py async def get_spot_market_liability ( self , market_index = None , margin_category = None , liquidation_buffer = None , include_open_orders = None , ): user = await self . get_user () total_liability = 0 for position in user . spot_positions : if is_spot_position_available ( position ) or ( market_index is not None and position . market_index != market_index ): continue spot_market = await self . get_spot_market ( position . market_index ) if position . market_index == QUOTE_ASSET_BANK_INDEX : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) value = token_amount * weight / SPOT_WEIGHT_PRECISION total_liability += value continue else : continue oracle_data = await self . get_spot_oracle_data ( spot_market ) if not include_open_orders : if str ( position . balance_type ) == \"SpotBalanceType.Borrow()\" : token_amount = get_token_amount ( position . scaled_balance , spot_market , position . balance_type ) liability_value = get_spot_liability_value ( token_amount , oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += liability_value continue else : continue ( worst_case_token_amount , worst_case_quote_amount , ) = get_worst_case_token_amounts ( position , spot_market , oracle_data ) if worst_case_token_amount < 0 : baa_value = get_spot_liability_value ( abs ( worst_case_token_amount ), oracle_data , spot_market , margin_category , liquidation_buffer , user . max_margin_ratio , ) total_liability += baa_value if worst_case_quote_amount < 0 : weight = SPOT_WEIGHT_PRECISION if margin_category == MarginCategory . INITIAL : weight = max ( weight , user . max_margin_ratio ) weighted_value = ( abs ( worst_case_quote_amount ) * weight / SPOT_WEIGHT_PRECISION ) total_liability += weighted_value return total_liability","title":"get_spot_market_liability()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_spot_oracle_data","text":"Source code in driftpy/drift_user.py async def get_spot_oracle_data ( self , spot_market : SpotMarket ) -> Optional [ OraclePriceData ]: return await self . drift_client . get_oracle_price_data ( spot_market . oracle )","title":"get_spot_oracle_data()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_state","text":"Source code in driftpy/drift_user.py async def get_state ( self ) -> State : return await self . drift_client . get_state ()","title":"get_state()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_total_collateral","text":"Source code in driftpy/drift_user.py async def get_total_collateral ( self , margin_category : Optional [ MarginCategory ] = None ) -> int : spot_collateral = await self . get_spot_market_asset_value ( margin_category , include_open_orders = True , ) pnl = await self . get_unrealized_pnl ( True , with_weight_margin_category = margin_category ) total_collateral = spot_collateral + pnl return total_collateral","title":"get_total_collateral()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_total_perp_liability","text":"Source code in driftpy/drift_user.py async def get_total_perp_liability ( self , margin_category : Optional [ MarginCategory ] = None , liquidation_buffer : Optional [ int ] = 0 , include_open_orders : bool = False , ): user = await self . get_user () unrealized_pnl = 0 for position in user . perp_positions : market = await self . get_perp_market ( position . market_index ) if position . lp_shares > 0 : pass price = ( await self . get_perp_oracle_data ( market )) . price base_asset_amount = ( calculate_worst_case_base_asset_amount ( position ) if include_open_orders else position . base_asset_amount ) base_value = ( abs ( base_asset_amount ) * price / ( AMM_TO_QUOTE_PRECISION_RATIO * PRICE_PRECISION ) ) if margin_category is not None : margin_ratio = calculate_market_margin_ratio ( market , abs ( base_asset_amount ), margin_category ) if margin_category == MarginCategory . INITIAL : margin_ratio = max ( margin_ratio , user . max_margin_ratio ) if liquidation_buffer is not None : margin_ratio += liquidation_buffer base_value = base_value * margin_ratio / MARGIN_PRECISION unrealized_pnl += base_value return unrealized_pnl","title":"get_total_perp_liability()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_unrealized_pnl","text":"Source code in driftpy/drift_user.py async def get_unrealized_pnl ( self , with_funding : bool = False , market_index : int = None , with_weight_margin_category : Optional [ MarginCategory ] = None , ): user = await self . get_user () quote_spot_market = await self . get_spot_market ( QUOTE_ASSET_BANK_INDEX ) unrealized_pnl = 0 position : PerpPosition for position in user . perp_positions : if market_index is not None and position . market_index != market_index : continue market = await self . get_perp_market ( position . market_index ) oracle_data = await self . get_perp_oracle_data ( market ) position_unrealized_pnl = calculate_position_pnl_with_oracle ( market , position , oracle_data , with_funding ) if with_weight_margin_category is not None : if position_unrealized_pnl > 0 : unrealized_asset_weight = calculate_unrealized_asset_weight ( market , quote_spot_market , position_unrealized_pnl , with_weight_margin_category , oracle_data , ) position_unrealized_pnl = ( position_unrealized_pnl * unrealized_asset_weight / SPOT_WEIGHT_PRECISION ) unrealized_pnl += position_unrealized_pnl return unrealized_pnl","title":"get_unrealized_pnl()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user","text":"Source code in driftpy/drift_user.py async def get_user ( self ) -> User : return ( await self . account_subscriber . get_user_account_and_slot ()) . data","title":"get_user()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user_position","text":"Source code in driftpy/drift_user.py async def get_user_position ( self , market_index : int , ) -> Optional [ PerpPosition ]: user = await self . get_user () found = False for position in user . perp_positions : if position . market_index == market_index and not is_available ( position ): found = True break if not found : return None return position","title":"get_user_position()"},{"location":"clearing_house_user/#driftpy.drift_user.DriftUser.get_user_spot_position","text":"Source code in driftpy/drift_user.py async def get_user_spot_position ( self , market_index : int , ) -> Optional [ SpotPosition ]: user = await self . get_user () found = False for position in user . spot_positions : if ( position . market_index == market_index and not is_spot_position_available ( position ) ): found = True break if not found : return None return position","title":"get_user_spot_position()"}]} \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 0dd6267e..4c7447d4 100644 Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ